Prop Shield Beta Test

Status
Not open for further replies.
Attempt at making a Prop shield variant of the WavFilePlayer

I was trying to hack the WAV player example to use the prop shield flash memory, and I'm not sure I'm missing something obvious. After posting it, I did discover I forgot to enable the SerialFlash chip, and I edited to to add that initialization, and corrected the pin for the AMP.

First of all, I was using this sketch to test to see if the speaker, etc. was connected, and I could use +/- to increase/decrease the pitch, and it works fine:

Code:
#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include <Audio.h>
#include <SerialFlash.h>

// from: https://forum.pjrc.com/threads/33328-Prop-Shield-Beta-Test?p=99236&viewfull=1#post99236
// modified by Michael Meissner

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=180,469
AudioOutputAnalog        dac1;           //xy=380,468
AudioConnection          patchCord1(sine1, dac1);
// GUItool: end automatically generated code

int freq = 1000;

void setup() {
  Serial.begin(115200);
  while (!Serial)
    ;
  Serial.println("Setting up");
  pinMode(5, OUTPUT);
  digitalWrite(5, 1);		// Enable Amplified.
  AudioMemory(12);
  sine1.amplitude(1.0);
  sine1.frequency(freq);
  Serial.println("Send + to increase freq, - to decrease freq, a to turn off amp, A to turn on amp, or num for freq.");
}

void loop()
{
  if (Serial.available()) {
    int ch = Serial.read();
    switch (ch)
      {
      case '+':
	freq += 100;
	sine1.frequency(freq);
	Serial.print ("New frequency ");
	Serial.println (freq);
	break;

      case '-':
	freq -= 100;
	sine1.frequency(freq);
	Serial.print ("New frequency ");
	Serial.println (freq);
	break;

      case 'a':
	digitalWrite (5, 0);
	Serial.println ("Amp off");
	break;

      case 'A':
	digitalWrite (5, 1);
	Serial.println ("Amp on");
	break;

      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
	{
	  bool looping = true;
	  freq = ch - '0';
	  do
	    {
	      if (Serial.available ())
		{
		  ch = Serial.read ();
		  if (ch >= '0' && ch <= '9')
		    freq = (freq * 10) + (ch - '0');
		  else
		    looping = false;
		}
	    }
	  while (looping);
	}

	Serial.print ("New frequency ");
	Serial.println (freq);
	sine1.frequency(freq);
	break;

      case ' ':
      case '\n':
      case '\t':
      case '\r':
	break;

      default:
	Serial.print ("Unknown character '");
	Serial.print ((char) ch);
	Serial.print ("'");
      }
  }
}

I converted 4 WAV files of Halloween sounds to RAW using the following command on Linux:

Code:
$ for x in SDTEST{1,2,3,4}; do sox $x.WAV --bits 16 --rate 44100 --channels 1 $x.RAW; done

I erased the flash memory with: ./hardware/teensy/avr/libraries/SerialFlash/examples/EraseEverything/EraseEverything.ino

I downloaded TeensyTransfer to the Teensy, and used teensytransfer to copy the 4 RAW files to the flash memory:

Code:
$ teensytransfer -l
$ for x in SDTEST{1,2,3,4}; do teensytransfer -w $x.RAW; done
$ teensytransfer -l
  232072 SDTEST1.RAW
  382464 SDTEST2.RAW
  203676 SDTEST3.RAW
  296704 SDTEST4.RAW

I uploaded this sketch to the Teensy:

Code:
// Originally from Teensy release:
// hardware/teensy/avr/libraries/Audio/examples/WavFilePlayer/WavFilePlayer.ino
//
// Simple WAV file player example
//
// Three types of output may be used, by configuring the code below.
//
//   1: Digital I2S - Normally used with the audio shield:
//         http://www.pjrc.com/store/teensy3_audio.html
//
//   2: Digital S/PDIF - Connect pin 22 to a S/PDIF transmitter
//         https://www.oshpark.com/shared_projects/KcDBKHta
//
//   3: Analog DAC - Connect the DAC pin to an amplified speaker
//         http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
//
// To configure the output type, first uncomment one of the three
// output objects.  If not using the audio shield, comment out
// the sgtl5000_1 lines in setup(), so it does not wait forever
// trying to configure the SGTL5000 codec chip.
//
// The SD card may connect to different pins, depending on the
// hardware you are using.  Uncomment or configure the SD card
// pins to match your hardware.
//
// Data files to put on your SD card can be downloaded here:
//   http://www.pjrc.com/teensy/td_libs_AudioDataFiles.html
//
// This example code is in the public domain.

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySerialflashRaw playRaw1;
AudioOutputAnalog	audioOutput;

#define PROP_AMP_ENABLE		5
#define FLASH_CHIP_SELECT           6

void setup() {
  Serial.begin(9600);

  // wait up to 3 seconds for the Serial device to become available
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 3000))
    ;

  Serial.println ("Start prop shield wav player");

  // Enable the amplifier on the prop shield
  pinMode(PROP_AMP_ENABLE, OUTPUT);
  digitalWrite(PROP_AMP_ENABLE, HIGH);

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(8);

  // Start SerialFlash
  if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
    while (1)
      {
	Serial.println ("Cannot access SPI Flash chip");
	delay (1000);
      }
  }
}

void playFile(const char *filename)
{
  Serial.print("Playing file: ");
  Serial.println(filename);

  // Start playing the file.  This sketch continues to
  // run while the file plays.
  playRaw1.play(filename);

  // A brief delay for the library read WAV info
  delay(5);

  // Simply wait for the file to finish playing.
  while (playRaw1.isPlaying()) {
    // uncomment these lines if you audio shield
    // has the optional volume pot soldered
    //float vol = analogRead(15);
    //vol = vol / 1024;
    // sgtl5000_1.volume(vol);
  }
}


void loop() {
  playFile("SDTEST1.RAW");  // filenames are always uppercase 8.3 format
  delay(500);
  playFile("SDTEST2.RAW");
  delay(500);
  playFile("SDTEST3.RAW");
  delay(500);
  playFile("SDTEST4.RAW");
  delay(1500);
}

And it hangs after printing Playing the SDTEST1.RAW lin.

I put the .WAV and .RAW files here: http://www.the-meissners.org/tmp/SDTEST.zip.
 
Last edited:
I've received and assembled my prop shield (awesome bit of kit!) and did some benchmarking of the actual filter compute methods:

Teensy 3.2 @ 120MHz
NXPSensorFusion - 3500 us
Madgwick - 225uS
Mahony - 127uS

Notes and observations:

- In the Madgwick example, I believe filter.updateIMU should be changed as a default to filter.update (which is commented out on the line below).
- The Mahony example gives me a -14 degree Roll offset compared to the other 2.
- I was not able to get the calibration gui.exe to work on Windows 7 without opening Arduino monitor first to trigger data sending. It worked fine on OSX 10.11.4 first time.
- More usage is required but it feels like the NXPSensorFusion is currently giving the best results which may make it worth the CPU load.
 
Probably, I'll look at it tonight. As I said, I probably was missing something obvious. I didn't use the audio tool, but instead tried to hack up the WavFilePlayer example.

Funny thing - I decided to try it - it ran FINE with no files of those names actually on the flash. I put the files on from the ZIP and like @MM - it prints this and stops:
Start prop shield wav player
Playing file: SDTEST1.RAW
 
Probably, I'll look at it tonight. As I said, I probably was missing something obvious. I didn't use the audio tool, but instead tried to hack up the WavFilePlayer example.

i added AudioConnection patchCord1(playRaw1, audioOutput);
to the sketch and it is playing TOPGUN.RAW clip (24s) just fine!
I converted audio ogg to wav to raw and teensytransfer TOPGUN.RAW 2116800 bytes

Take my breath away ...
 
Last edited:
Thanks Manitou. I missed the AudioConnection. It works fine now.

Defragster: The sounds are from soundbible.com, which includes public domain sounds (the first, third, and fourth) and personal use only (second) sounds:

Paul, I think it would be helpful if 1.28 had something similar the above exercise (feel free to copy/edit my version or use your own version) to show a useful way to use the prop shield, assuming TeensyTransfer is also included. However, I suspect you might not want to use the werewolf howling, since that is not public domain. Perhaps this version of many wolves howling, which is PD: http://soundbible.com/278-Many-Wolves-Howling.html.

FWIW, the sounds you provide for the audio shield are too large to use on the prop shield.

<edit>
The speaker I'm using is the Breadboard-Friendly PCB Mount Mini Speaker - 8ohm, 0.2w that I got from Adafruit: https://www.adafruit.com/products/1898.

I'm not a fan of their thin plastic speaker (https://www.adafruit.com/products/1891) or their mini metal speaker (https://www.adafruit.com/products/1890), since the wires seems to come unsoldered, and there is nothing to attach the speaker to
 
Last edited:
Paul, I know the LC (witout) prop shield does not have the 3 sensors, but does it still have the pull-up resistors so SDA/SCL can be used for an i2c bus? Or would I need to add the appropriate resistors with the LC prop shield?
 
Last edited:
Here's a new version of the calibration program.

Mac:
http://www.pjrc.com/teensy/beta/imuread/MotionCal.dmg

Windows:
http://www.pjrc.com/teensy/beta/imuread/MotionCal.exe

Linux 64 bit:
http://www.pjrc.com/teensy/beta/imuread/MotionCal.linux64

Changes since the last version:

  • Variance error automatically improves, when gaps under 25%
  • Fix crash on quit
  • Fix Teensy stuck in while (!Serial) with Windows - TODO: needs testing
  • Windows and Mac versions signed - TODO: needs verify on El Capitan
  • Mac version uses DMG disk image
  • Name changed to "MotionCal"
 
Oh, I should mention the variance reduction begins slowly when gaps gets to 25%. The rate steadily increases as gaps is reduced, until gaps gets to 1% or less.

At least that's how it's supposed to work.....

In theory this should allow getting much better calibration, with all errors under 2% without a huge amount of work. Maybe? Please let me know how it actually works for you in practice?
 
[Edit: Success!
Screen Shot 2016-04-01 at 12.52.22 PM.png
Things I was missing:
  1. The URL in the About box does point to a page that points to the Git Hub project that has the Teensy side of the calibration. It would still be good for the PC side "Motion Sensor Calibration Tool" to report troubles communicating with the Teensy/Prop shield.
  2. No Teensy files need to be edited if the entire directory from Git Hub is copied into ~/Documents/Arduino/libraries. I'm using Arduino 1.6.8/Teensyduino 1.28-beta1 on OS X 10.9.5 Mavericks.
  3. Can't have the Arduino IDE running while MotionCal is trying to talk to the Teensy. May need to restart MotionCal or the Teensy multiple times before they find each other.
  4. Some patterns of movement during calibration lead to convergence quicker than others. Waving the Prop Shield around seems to help. Putting it down on the desk, not so much.

Things I'm still wondering about:
  1. Why does the calibration get dramatically worse sometimes?
  2. Why does the sphere of dots slowly roll when the Prop Shield is relatively still and certainly not rolling?
  3. Why do the Accelerometer and Gyroscope fields report all zeros?
  4. After "Send Calibration" is performed, is there anything needed in subsequent sketches to make use of the calibration?
  5. Is there any way to capture the calibration data or metadata other than attempting a screen shot as quickly as possible after sending the calibration?
  6. Which parameter(s) should be optimized? I'm assuming first priority would be getting the "Fit Error" as low as possible. Is 1.8% a good number?
  7. How long should the calibration process take? It seems long to me.
  8. When should re-calibration be done? Obviously if the environment changes or the readings get worse, but is it expected that it's done daily, annually, just once, etc?
]


MotionCal feature request: Add a menu item to load the appropriate hex file to the Teensy.

If this is not a good idea, perhaps add some help text with the URL of the instructions for preparing the Teensy for Prop Shield calibration.


[Edit: and error messages about being unable to communicate with the Teensy/Prop Shield would be helpful, too.]
 
Last edited:
I'm wondering whether anybody has started making a prop shield version of a light saber? It would seem to be the right size to fit in the general saber handles, and all you would need is a speaker, battery, and appropriate LEDs.
 
I'm wondering whether anybody has started making a prop shield version of a light saber? It would seem to be the right size to fit in the general saber handles, and all you would need is a speaker, battery, and appropriate LEDs.

I've been debating whether or not to find someone in the 501st or Rebel Legion who looks like a good candidate to send a Prop Shield to do just that. :)
 
Under Ubantu 14.04 do not get a port using MotionCal.linux64, menu item is there nothing under it when clicked. Can see the data spew in serial monitor but with monitor closed nothing in MotionCal.
 
That's very strange. To show up in the ports menu, the /dev/ttyACM0 file only needs to exist when the readdir() is used on "/dev/". It doesn't even need to be readable or usable to appear in the menu.

I develop on Ubuntu 14.04, where it's always worked. So I have no idea why or how it could possible do such a thing!
 
Status
Not open for further replies.
Back
Top