Update Play RAD

Update Play RAD

This updates the Play RAD example to work with the current library
version.

--- examples/OPL2AudioBoard/PlayRAD/PlayRAD.ino
+++ examples/OPL2AudioBoard/PlayRAD/PlayRAD.ino
@@ -52,8 +52,8 @@

 // Different note F-numbers stored in program memory.
 const short noteFrequencies[12] PROGMEM = {
-  0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5,
-  0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE
+	0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5,
+	0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE
 };

@@ -86,28 +86,28 @@

 void setup() {
-  SD.begin(7);
-
-  // Load one of the included RAD files.
-  loadRadFile("adlibsp.rad");
-  // loadRadFile("shoot.rad");
-  // loadRadFile("action.rad");
-
-  initPlayer();
+	SD.begin(7);
+
+	// Load one of the included RAD files.
+	loadRadFile("adlibsp.rad");
+	// loadRadFile("shoot.rad");
+	// loadRadFile("action.rad");
+
+	initPlayer();
 }

 void loop() {
-  unsigned long time = millis();
-
-  if (order < songLength) {
-    playMusic();
-  }
-
-  // Calculate delay based on song speed and time spent in player routine.
-  int timeSpent = millis() - time;
-  int wait = max(0, (hasSlowTimer ? 55 : 20) - timeSpent);
-  delay(wait);
+	unsigned long time = millis();
+
+	if (order < songLength) {
+		playMusic();
+	}
+
+	// Calculate delay based on song speed and time spent in player routine.
+	int timeSpent = millis() - time;
+	int wait = max(0, (hasSlowTimer ? 55 : 20) - timeSpent);
+	delay(wait);
 }

@@ -115,23 +115,19 @@
  * Load instrument data for the given channel.
  */
 void setInstrument(byte channel, byte instrumentIndex) {
-  byte registerOffset;
-
-  registerOffset = opl2.getRegisterOffset(channel, CARRIER);
-  opl2.setRegister(0x20 + registerOffset, instruments[instrumentIndex][0]);
-  opl2.setRegister(0x40 + registerOffset, instruments[instrumentIndex][2]);
-  opl2.setRegister(0x60 + registerOffset, instruments[instrumentIndex][4]);
-  opl2.setRegister(0x80 + registerOffset, instruments[instrumentIndex][6]);
-  opl2.setRegister(0xE0 + registerOffset, instruments[instrumentIndex][9] & 0x0F);
-
-  registerOffset = opl2.getRegisterOffset(channel, MODULATOR);
-  opl2.setRegister(0x20 + registerOffset, instruments[instrumentIndex][1]);
-  opl2.setRegister(0x40 + registerOffset, instruments[instrumentIndex][3]);
-  opl2.setRegister(0x60 + registerOffset, instruments[instrumentIndex][5]);
-  opl2.setRegister(0x80 + registerOffset, instruments[instrumentIndex][7]);
-  opl2.setRegister(0xE0 + registerOffset, (instruments[instrumentIndex][9] & 0xF0) >> 4);
-
-  opl2.setRegister(0xC0 + channel, instruments[instrumentIndex][8]);
+	opl2.setOperatorRegister(0x20, channel, CARRIER, instruments[instrumentIndex][0]);
+	opl2.setOperatorRegister(0x40, channel, CARRIER, instruments[instrumentIndex][2]);
+	opl2.setOperatorRegister(0x60, channel, CARRIER, instruments[instrumentIndex][4]);
+	opl2.setOperatorRegister(0x80, channel, CARRIER, instruments[instrumentIndex][6]);
+	opl2.setOperatorRegister(0xE0, channel, CARRIER, instruments[instrumentIndex][9] & 0x0F);
+
+	opl2.setOperatorRegister(0x20, channel, MODULATOR, instruments[instrumentIndex][1]);
+	opl2.setOperatorRegister(0x40, channel, MODULATOR, instruments[instrumentIndex][3]);
+	opl2.setOperatorRegister(0x60, channel, MODULATOR, instruments[instrumentIndex][5]);
+	opl2.setOperatorRegister(0x80, channel, MODULATOR, instruments[instrumentIndex][7]);
+	opl2.setOperatorRegister(0xE0, channel, MODULATOR, (instruments[instrumentIndex][9] & 0xF0) >> 4);
+
+	opl2.setChannelRegister(0xC0, channel, instruments[instrumentIndex][8]);
 }

@@ -139,10 +135,10 @@
  * Play a note on the given channel.
  */
 void playNote(byte channel, byte octave, byte note) {
-  opl2.setKeyOn(channel, false);
-  opl2.setBlock(channel, octave + (note / 12));
-  opl2.setFNumber(channel, pgm_read_word_near(noteFrequencies + (note % 12)));
-  opl2.setKeyOn(channel, true);
+	opl2.setKeyOn(channel, false);
+	opl2.setBlock(channel, octave + (note / 12));
+	opl2.setFNumber(channel, pgm_read_word_near(noteFrequencies + (note % 12)));
+	opl2.setKeyOn(channel, true);
 }

@@ -150,29 +146,29 @@
  * Slide the pitch of a channel by a given F-number amount and return the new block + F-number.
  */
 unsigned int pitchAdjust(byte channel, short amount) {
-  byte block = opl2.getBlock(channel);
-  short fNumber = opl2.getFNumber(channel);
-  fNumber = max(0x000, min(fNumber + amount, 0x3FF));
-
-  // Drop one octave (if possible) when the F-number drops below octave minimum.
-  if (fNumber < FNUMBER_MIN) {
-    if (block > 0) {
-      block --;
-      fNumber = FNUMBER_MAX - (FNUMBER_MIN - fNumber);
-    }
-
-  // Increase one octave (if possible) when the F-number reaches above octave maximum.
-  } else if (fNumber > FNUMBER_MAX) {
-    if (block < 7) {
-      block ++;
-      fNumber = FNUMBER_MIN + (fNumber - FNUMBER_MAX);
-    }
-  }
-
-  // Set new octave and frequency and return combind octave + F-number value.
-  opl2.setBlock(channel, block);
-  opl2.setFNumber(channel, fNumber);
-  return (block << 12) + fNumber;
+	byte block = opl2.getBlock(channel);
+	short fNumber = opl2.getFNumber(channel);
+	fNumber = max(0x000, min(fNumber + amount, 0x3FF));
+
+	// Drop one octave (if possible) when the F-number drops below octave minimum.
+	if (fNumber < FNUMBER_MIN) {
+		if (block > 0) {
+			block --;
+			fNumber = FNUMBER_MAX - (FNUMBER_MIN - fNumber);
+		}
+
+	// Increase one octave (if possible) when the F-number reaches above octave maximum.
+	} else if (fNumber > FNUMBER_MAX) {
+		if (block < 7) {
+			block ++;
+			fNumber = FNUMBER_MIN + (fNumber - FNUMBER_MAX);
+		}
+	}
+
+	// Set new octave and frequency and return combind octave + F-number value.
+	opl2.setBlock(channel, block);
+	opl2.setFNumber(channel, fNumber);
+	return (block << 12) + fNumber;
 }

@@ -181,29 +177,29 @@
  * destination pitch is reached.
  */
 void pitchAdjustToNote(byte channel) {
-  if (pitchSlideDest[channel] == 0x0000) return;
-
-  unsigned int slidePos = opl2.getBlock(channel) << 12;
-  slidePos += opl2.getFNumber(channel);
-
-  // Slide pitch up and compensate any overshoot.
-  if (slidePos < pitchSlideDest[channel]) {
-    slidePos = pitchAdjust(channel, pitchSlideSpeed[channel]);
-    if (slidePos >= pitchSlideDest[channel]) {
-      opl2.setBlock  (channel, (pitchSlideDest[channel] & 0xF000) >> 12);
-      opl2.setFNumber(channel,  pitchSlideDest[channel] & 0x0FFF);
-      pitchSlideDest[channel] = 0x0000;
-    }
-
-  // Slide pitch down and compensate for any undershoot.
-  } else if (slidePos > pitchSlideDest[channel]) {
-    slidePos = pitchAdjust(channel, -pitchSlideSpeed[channel]);
-    if (slidePos <= pitchSlideDest[channel]) {
-      opl2.setBlock  (channel, (pitchSlideDest[channel] & 0xF000) >> 12);
-      opl2.setFNumber(channel,  pitchSlideDest[channel] & 0x0FFF);
-      pitchSlideDest[channel] = 0x0000;
-    }
-  }
+	if (pitchSlideDest[channel] == 0x0000) return;
+
+	unsigned int slidePos = opl2.getBlock(channel) << 12;
+	slidePos += opl2.getFNumber(channel);
+
+	// Slide pitch up and compensate any overshoot.
+	if (slidePos < pitchSlideDest[channel]) {
+		slidePos = pitchAdjust(channel, pitchSlideSpeed[channel]);
+		if (slidePos >= pitchSlideDest[channel]) {
+			opl2.setBlock  (channel, (pitchSlideDest[channel] & 0xF000) >> 12);
+			opl2.setFNumber(channel,  pitchSlideDest[channel] & 0x0FFF);
+			pitchSlideDest[channel] = 0x0000;
+		}
+
+	// Slide pitch down and compensate for any undershoot.
+	} else if (slidePos > pitchSlideDest[channel]) {
+		slidePos = pitchAdjust(channel, -pitchSlideSpeed[channel]);
+		if (slidePos <= pitchSlideDest[channel]) {
+			opl2.setBlock  (channel, (pitchSlideDest[channel] & 0xF000) >> 12);
+			opl2.setFNumber(channel,  pitchSlideDest[channel] & 0x0FFF);
+			pitchSlideDest[channel] = 0x0000;
+		}
+	}
 }

@@ -211,15 +207,15 @@
  * Adjust the volume of a channel by the gven amount.
  */
 void volumeAdjust(byte channel, byte amount) {
-  byte volume = opl2.getVolume(channel, CARRIER);
-
-  if (amount > 0 && amount < 50) {
-    volume = min(63, volume + amount);
-  } else if (amount > 50 && amount < 100) {
-    volume = max(0, volume - (amount - 50));
-  }
-
-  opl2.setVolume(channel, CARRIER, volume);
+	byte volume = opl2.getVolume(channel, CARRIER);
+
+	if (amount > 0 && amount < 50) {
+		volume = min(63, volume + amount);
+	} else if (amount > 50 && amount < 100) {
+		volume = max(0, volume - (amount - 50));
+	}
+
+	opl2.setVolume(channel, CARRIER, volume);
 }

@@ -227,42 +223,42 @@
  * Read the next line in the pattern from the current file position.
  */
 void readLine() {
-  // Reset note data on each channel.
-  for (byte i = 0; i < 9; i ++) {
-    channelNote[i] = 0x0000;
-  }
-
-  // If the previous line was the last line of the pattern then we're done.
-  if (endOfPattern) {
-    return;
-  }
-
-  // If the next line number does not match our current line then it's empty
-  // so there's nothing to do for us here.
-  byte lineNumber = radFile.read();
-  if ((lineNumber & 0x3F) != line) {
-    radFile.seekSet(radFile.curPosition() - 1);
-    return;
-  }
-
-  // Set end of pattern marker if this is the last line in the pattern.
-  endOfPattern = lineNumber & 0x80;
-
-  // Read note and effect data for each channel.
-  bool isLastChannel = false;
-  do {
-    byte channelNumber = radFile.read();
-    isLastChannel = channelNumber & 0x80;
-    channelNumber = channelNumber & 0x0F;
-
-    channelNote[channelNumber]  = radFile.read() << 8;
-    channelNote[channelNumber] += radFile.read();
-    if (channelNote[channelNumber] & 0x000F) {
-      efftectParameter[channelNumber] = radFile.read();
-    } else {
-      efftectParameter[channelNumber] = 0x00;
-    }
-  } while(!isLastChannel);
+	// Reset note data on each channel.
+	for (byte i = 0; i < 9; i ++) {
+		channelNote[i] = 0x0000;
+	}
+
+	// If the previous line was the last line of the pattern then we're done.
+	if (endOfPattern) {
+		return;
+	}
+
+	// If the next line number does not match our current line then it's empty
+	// so there's nothing to do for us here.
+	byte lineNumber = radFile.read();
+	if ((lineNumber & 0x3F) != line) {
+		radFile.seekSet(radFile.curPosition() - 1);
+		return;
+	}
+
+	// Set end of pattern marker if this is the last line in the pattern.
+	endOfPattern = lineNumber & 0x80;
+
+	// Read note and effect data for each channel.
+	bool isLastChannel = false;
+	do {
+		byte channelNumber = radFile.read();
+		isLastChannel = channelNumber & 0x80;
+		channelNumber = channelNumber & 0x0F;
+
+		channelNote[channelNumber]  = radFile.read() << 8;
+		channelNote[channelNumber] += radFile.read();
+		if (channelNote[channelNumber] & 0x000F) {
+			efftectParameter[channelNumber] = radFile.read();
+		} else {
+			efftectParameter[channelNumber] = 0x00;
+		}
+	} while(!isLastChannel);
 }

@@ -272,28 +268,28 @@
  * reached we may loop back to the beginning if loopSong is true.
  */
 void nextOrder(byte startLine = 0) {
-  // Increment order and read patternIndex, may loop song when we've reached the end.
-  order ++;
-  if (order >= songLength && loopSong) {
-    order = 0;
-  }
-  radFile.seekSet(orderListOffset + order);
-  byte patternIndex = radFile.read();
-
-  // If bit 7 is set then we're looking at an order jump.
-  if (patternIndex & 0x80) {
-    order = patternIndex & 0x7F;
-    radFile.seekSet(orderListOffset + order);
-    patternIndex = radFile.read();
-  }
-
-  // Set file offset to the start of the next order and skip lines until we're
-  // at the requested startLine.
-  radFile.seekSet(patternOffsets[patternIndex]);
-  endOfPattern = false;
-  for (line = 0; line < startLine; line ++) {
-    readLine();
-  }
+	// Increment order and read patternIndex, may loop song when we've reached the end.
+	order ++;
+	if (order >= songLength && loopSong) {
+		order = 0;
+	}
+	radFile.seekSet(orderListOffset + order);
+	byte patternIndex = radFile.read();
+
+	// If bit 7 is set then we're looking at an order jump.
+	if (patternIndex & 0x80) {
+		order = patternIndex & 0x7F;
+		radFile.seekSet(orderListOffset + order);
+		patternIndex = radFile.read();
+	}
+
+	// Set file offset to the start of the next order and skip lines until we're
+	// at the requested startLine.
+	radFile.seekSet(patternOffsets[patternIndex]);
+	endOfPattern = false;
+	for (line = 0; line < startLine; line ++) {
+		readLine();
+	}
 }

@@ -301,16 +297,16 @@
  * Initialize the OPL2 board and load the first line of the first order.
  */
 void initPlayer() {
-  opl2.begin();
-  opl2.setWaveFormSelect(true);
-  opl2.setPercussion(false);
-  speed = initialSpeed;
-
-  order = -1;
-  line = 0;
-  tick = 0;
-  nextOrder();
-  readLine();
+	opl2.begin();
+	opl2.setWaveFormSelect(true);
+	opl2.setPercussion(false);
+	speed = initialSpeed;
+
+	order = -1;
+	line = 0;
+	tick = 0;
+	nextOrder();
+	readLine();
 }

@@ -318,104 +314,104 @@
  * Process one tick of the current line and advance the song if needed.
  */
 void playMusic() {
-  for (byte channel = 0; channel < 9; channel ++) {
-    unsigned short channelData = channelNote[channel];
-    byte effect = channelData & 0x000F;
-
-    if (tick == 0) {
-      byte instrument = ((channelData & 0x8000) >> 11) + ((channelData & 0x00F0) >> 4);
-      byte octave     = (channelData & 0x7000) >> 12;
-      byte note       = (channelData & 0x0F00) >> 8;
-
-      // Set instrument.
-      if (instrument > 0) {
-        setInstrument(channel, instrument - 1);
-      }
-
-      // Stop note.
-      if (note == 0x0F) {
-        opl2.setKeyOn(channel, false);
-      }
-
-      // Trigger note.
-      else if (note && effect != EFFECT_NOTE_SLIDE_TO) {
-        playNote(channel, octave, note);
-      }
-
-      // Process line effects.
-      switch(effect) {
-        case EFFECT_NOTE_SLIDE_TO: {
-          if (note > 0x00 && note < 0x0F) {
-            pitchSlideDest[channel]  = (octave + (note / 12)) << 12;
-            pitchSlideDest[channel] += pgm_read_word_near(noteFrequencies + (note % 12));
-            pitchSlideSpeed[channel] = efftectParameter[channel];
-          }
-          break;
-        }
-
-        case EFFECT_SET_VOLUME: {
-          opl2.setVolume(channel, CARRIER, max(0, min(64 - efftectParameter[channel], 63)));
-          break;
-        }
-
-        case EFFECT_PATTERN_BREAK: {
-          patternBreak = efftectParameter[channel];
-          break;
-        }
-
-        case EFFECT_SET_SPEED: {
-          speed = efftectParameter[channel];
-          break;
-        }
-      }
-    }
-
-    // Process tick effects.
-    switch(effect) {
-      case EFFECT_NOTE_SLIDE_UP: {
-        pitchAdjust(channel, efftectParameter[channel]);
-        break;
-      }
-
-      case EFFECT_NOTE_SLIDE_DOWN: {
-        pitchAdjust(channel, -efftectParameter[channel]);
-        break;
-      }
-
-      case EFFECT_NOTE_SLIDE_VOLUME: {
-        pitchAdjustToNote(channel);
-        volumeAdjust(channel, efftectParameter[channel]);
-        break;
-      }
-
-      case EFFECT_NOTE_SLIDE_TO: {
-        pitchAdjustToNote(channel);
-        break;
-      }
-
-      case EFFECT_VOLUME_SLIDE: {
-        volumeAdjust(channel, efftectParameter[channel]);
-        break;
-      }
-    }
-  }
-
-  // Advance song.
-  tick = (tick + 1) % speed;
-  if (tick == 0) {
-    if (patternBreak == 0xFF) {
-      line = (line + 1) % 64;
-      if (line == 0) {
-        nextOrder();
-      }
-    } else {
-      line = patternBreak;
-      patternBreak = 0xFF;
-      nextOrder();
-    }
-
-    readLine();
-  }
+	for (byte channel = 0; channel < 9; channel ++) {
+		unsigned short channelData = channelNote[channel];
+		byte effect = channelData & 0x000F;
+
+		if (tick == 0) {
+			byte instrument = ((channelData & 0x8000) >> 11) + ((channelData & 0x00F0) >> 4);
+			byte octave     = (channelData & 0x7000) >> 12;
+			byte note       = (channelData & 0x0F00) >> 8;
+
+			// Set instrument.
+			if (instrument > 0) {
+				setInstrument(channel, instrument - 1);
+			}
+
+			// Stop note.
+			if (note == 0x0F) {
+				opl2.setKeyOn(channel, false);
+			}
+
+			// Trigger note.
+			else if (note && effect != EFFECT_NOTE_SLIDE_TO) {
+				playNote(channel, octave, note);
+			}
+
+			// Process line effects.
+			switch(effect) {
+				case EFFECT_NOTE_SLIDE_TO: {
+					if (note > 0x00 && note < 0x0F) {
+						pitchSlideDest[channel]  = (octave + (note / 12)) << 12;
+						pitchSlideDest[channel] += pgm_read_word_near(noteFrequencies + (note % 12));
+						pitchSlideSpeed[channel] = efftectParameter[channel];
+					}
+					break;
+				}
+
+				case EFFECT_SET_VOLUME: {
+					opl2.setVolume(channel, CARRIER, max(0, min(64 - efftectParameter[channel], 63)));
+					break;
+				}
+
+				case EFFECT_PATTERN_BREAK: {
+					patternBreak = efftectParameter[channel];
+					break;
+				}
+
+				case EFFECT_SET_SPEED: {
+					speed = efftectParameter[channel];
+					break;
+				}
+			}
+		}
+
+		// Process tick effects.
+		switch(effect) {
+			case EFFECT_NOTE_SLIDE_UP: {
+				pitchAdjust(channel, efftectParameter[channel]);
+				break;
+			}
+
+			case EFFECT_NOTE_SLIDE_DOWN: {
+				pitchAdjust(channel, -efftectParameter[channel]);
+				break;
+			}
+
+			case EFFECT_NOTE_SLIDE_VOLUME: {
+				pitchAdjustToNote(channel);
+				volumeAdjust(channel, efftectParameter[channel]);
+				break;
+			}
+
+			case EFFECT_NOTE_SLIDE_TO: {
+				pitchAdjustToNote(channel);
+				break;
+			}
+
+			case EFFECT_VOLUME_SLIDE: {
+				volumeAdjust(channel, efftectParameter[channel]);
+				break;
+			}
+		}
+	}
+
+	// Advance song.
+	tick = (tick + 1) % speed;
+	if (tick == 0) {
+		if (patternBreak == 0xFF) {
+			line = (line + 1) % 64;
+			if (line == 0) {
+				nextOrder();
+			}
+		} else {
+			line = patternBreak;
+			patternBreak = 0xFF;
+			nextOrder();
+		}
+
+		readLine();
+	}
 }

@@ -423,36 +419,36 @@
  * Load the given RAD file from SD card.
  */
 void loadRadFile(char* fileName) {
-  radFile.open(fileName);
-
-  radFile.seekSet(0x11);
-  byte songProps = radFile.read();
-  hasSlowTimer = (songProps & 0x40) != 0x00;
-  initialSpeed = songProps & 0x1F;
-
-  // Skip song description block if available.
-  if ((songProps & 0x80) != 0x00) {
-    while (radFile.read() != 0x00);
-  }
-
-  // Read instruments.
-  byte instrumentNum = 0;
-  while ((instrumentNum = radFile.read()) != 0x00) {
-    instrumentNum --;
-    for (byte i = 0; i < 9; i ++) {
-      instruments[instrumentNum][i] = radFile.read();
-    }
-    instruments[instrumentNum][9]  =  radFile.read() & 0x07;
-    instruments[instrumentNum][9] += (radFile.read() & 0x07) << 4;
-  }
-
-  // Read song length, order list offset and skip order list.
-  songLength = radFile.read();
-  orderListOffset = radFile.curPosition();
-  radFile.seekSet(orderListOffset + songLength);
-
-  // Read pattern offsets.
-  for (byte i = 0; i < 32; i++) {
-    patternOffsets[i] = radFile.read() + (radFile.read() << 8);
-  }
-}
+	radFile.open(fileName);
+
+	radFile.seekSet(0x11);
+	byte songProps = radFile.read();
+	hasSlowTimer = (songProps & 0x40) != 0x00;
+	initialSpeed = songProps & 0x1F;
+
+	// Skip song description block if available.
+	if ((songProps & 0x80) != 0x00) {
+		while (radFile.read() != 0x00);
+	}
+
+	// Read instruments.
+	byte instrumentNum = 0;
+	while ((instrumentNum = radFile.read()) != 0x00) {
+		instrumentNum --;
+		for (byte i = 0; i < 9; i ++) {
+			instruments[instrumentNum][i] = radFile.read();
+		}
+		instruments[instrumentNum][9]  =  radFile.read() & 0x07;
+		instruments[instrumentNum][9] += (radFile.read() & 0x07) << 4;
+	}
+
+	// Read song length, order list offset and skip order list.
+	songLength = radFile.read();
+	orderListOffset = radFile.curPosition();
+	radFile.seekSet(orderListOffset + songLength);
+
+	// Read pattern offsets.
+	for (byte i = 0; i < 32; i++) {
+		patternOffsets[i] = radFile.read() + (radFile.read() << 8);
+	}
+}


Implement color palette (with the colors for unknown and happy switched around) and a don't do anything not even epsilon select action if the current context and desired context are the same.

--- RoverMain/RoverMain.ino
+++ RoverMain/RoverMain.ino
@@ -258,63 +258,70 @@

 void loop() {
 	//insert retrieving EEG return codes here
-	/*
+	//
 	byte ctxpair = reccodes2ctx();

 	switch((ctxpair & FROM_CTX_MASK) >> 4) {
 		case SAD:
-			strip.setPixelColor(0, strip.Color(0, 0 , 0));
+			strip.setPixelColor(0, strip.Color(0, 0 , 255));
 			break;
 		case MAD:
-			strip.setPixelColor(0, strip.Color(0, 0 , 0));
+			strip.setPixelColor(0, strip.Color(255, 0 , 0));
 			break;
 		case FEARFUL:
-			strip.setPixelColor(0, strip.Color(0, 0 , 0));
+			strip.setPixelColor(0, strip.Color(255, 0 , 14  0));
 			break;
 		case DISTRACTED:
-			strip.setPixelColor(0, strip.Color(0, 0 , 0));
+			strip.setPixelColor(0, strip.Color(165, 0 , 255));
 			break;
 		case HAPPY:
-			strip.setPixelColor(0, strip.Color(0, 0 , 0));
+			strip.setPixelColor(0, strip.Color(0, 255, 65));
 			break;
 		case CALM:
-			strip.setPixelColor(0, strip.Color(0, 0 , 0));
+			strip.setPixelColor(0, strip.Color(0, 248 , 255));
 			break;
 		case FOCUSED:
-			strip.setPixelColor(0, strip.Color(0, 0 , 0));
+			strip.setPixelColor(0, strip.Color(255, 255, 213));
 			break;
 		default:
-			strip.setPixelColor(0, strip.Color(0, 0 , 0));
+			strip.setPixelColor(0, strip.Color(255, 123 , 0));
 			break;
 	}

 	switch(ctxpair & TO_CTX_MASK) {
 		case SAD:
-			strip.setPixelColor(1, strip.Color(0, 0 , 0));
-			break;
+			strip.setPixelColor(1, strip.Color(0, 0 , 255));
+			break;
 		case MAD:
-			strip.setPixelColor(1, strip.Color(0, 0 , 0));
+			strip.setPixelColor(1, strip.Color(255, 0 , 0));
 			break;
 		case FEARFUL:
-			strip.setPixelColor(1, strip.Color(0, 0 , 0));
+			strip.setPixelColor(1, strip.Color(255, 0 , 140));
 			break;
 		case DISTRACTED:
-			strip.setPixelColor(1, strip.Color(0, 0 , 0));
+			strip.setPixelColor(1, strip.Color(165, 0 , 255));
 			break;
 		case HAPPY:
-			strip.setPixelColor(1, strip.Color(0, 0 , 0));
+			strip.setPixelColor(1, strip.Color(0, 255, 65));
 			break;
 		case CALM:
-			strip.setPixelColor(1, strip.Color(0, 0 , 0));
+			strip.setPixelColor(1, strip.Color(0, 248, 255));
 			break;
 		case FOCUSED:
-			strip.setPixelColor(1, strip.Color(0, 0 , 0));
+			strip.setPixelColor(1, strip.Color(255, 255 , 213));
 			break;
 		default:
-			strip.setPixelColor(1, strip.Color(0, 0 , 0));
+			strip.setPixelColor(1, strip.Color(255, 123 , 0));
 			break;
 	}
 	strip.show();
+
+	if (((ctxpair & FROM_CTX_MASK) >> 4) == (ctxpair & TO_CTX_MASK)) {
+		//don't do anything, not even the epsilon select,
+		//if the desired context and current context are the same
+		delay(2000);
+		return;
+	}

 	actionScore = epsilon_select(ctxpair, 10);
 	switch(actionScore.action) {
@@ -407,7 +414,7 @@
 		actionScore.score--;
 	}
 	db.updateRec(actionScore.id, EDB_REC actionScore);
-	*/
+	//
 }

 /*** Motor Functions ***/


Update SerialArduinoBridge.ino

Update SerialArduinoBridge.ino

Reduced documentation/license clutter.  Description and license info moved to README and LICENSE files.

--- SerialArduinoBridge.ino
+++ SerialArduinoBridge.ino
@@ -1,61 +1,10 @@
 /*********************************************************************
  *
-    ROSArduinoBridge - Adapted for Memorial University's RTbot and ARbot platforms by Andrew Vardy
+    SerialArduinoBridge - Adapted from ROSArduinoBridge for various robot platforms at Memorial University
     ------------------------------------------------------------------------------------------------
-    Changes made to the original:
-      - Undefined USE_BASE (this file)
-      - Adjusted pins referenced in servos.h to pins 9 and 10
-      - Commented out the inclusion of MegaEncoderCounter.h in encoder_driver (this seems unnecessary but was specifically called for: https://github.com/hbrobotics/ros_arduino_bridge )
-
+
     Andrew Vardy
-
-
-    Original documentation follows
-    -------------------------------
-
-    A set of simple serial commands to control a differential drive
-    robot and receive back sensor and odometry data. Default
-    configuration assumes use of an Arduino Mega + Pololu motor
-    controller shield + Robogaia Mega Encoder shield.  Edit the
-    readEncoder() and setMotorSpeed() wrapper functions if using
-    different motor controller or encoder method.
-
-    Created for the Pi Robot Project: http://www.pirobot.org
-    and the Home Brew Robotics Club (HBRC): http://hbrobotics.org
-
-    Authors: Patrick Goebel, James Nugen
-
-    Inspired and modeled after the ArbotiX driver by Michael Ferguson
-
-    Software License Agreement (BSD License)
-
-    Copyright (c) 2012, Patrick Goebel.
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-     * Redistributions of source code must retain the above copyright
-       notice, this list of conditions and the following disclaimer.
-     * Redistributions in binary form must reproduce the above
-       copyright notice, this list of conditions and the following
-       disclaimer in the documentation and/or other materials provided
-       with the distribution.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-    COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- *********************************************************************/
+*/

 #define USE_RTBOT      // Enable the RTbot code
 //#undef USE_RTBOT     // Disable the RTbot code


Doug Hilton - Modified to add ShowAll/HideAll command Modified to let ShowInterval and ShowRPM run without ShowAngle Modified to check that xv_config is not too big for EEPROM Modified to delete ShowDist/HideDist commands, since that functionality is subsumed by ShowAngle(s)

--- XV_Lidar_Controller.ino
+++ XV_Lidar_Controller.ino
@@ -18,6 +18,10 @@
  ****************************************************************************************
  Modified to add ShowCSV and HideCSV command - DSH
  Modified EEPROM configuration to add new values and delete old ones - DSH
+ Modified to add ShowAll/HideAll command - DSH
+ Modified to let ShowInterval and ShowRPM run without ShowAngle
+ Modified to check that xv_config is not too big for EEPROM
+ Modified to delete ShowDist/HideDist commands, since that functionality is subsumed by ShowAngle(s)

  See README for additional information

@@ -50,6 +54,7 @@
 const char szCURRENT_EEPROM_VERSION[6] = "1.3.0";    // as of 24NOV2015 - DSH

 const int _N_ANGLES = 360;                           // # of angles in a circle (0..359)
+const int  _EEPROM_SIZE = 1024;                      // Size of EEPROM, in bytes
 // These constants will let us read and write individual variables to the EEPROM - DSH
 const byte _BITS_PER_BYTE = 8;
 const byte _MASK_BYTE = (1 << _BITS_PER_BYTE) - 1;                // (value: 0xFF)
@@ -67,9 +72,8 @@
  */
 const byte _eOUT_UNKNOWN = 0;                 // Unknown or uninitialized (value: 0)
 const byte _eOUT_RAW = _eOUT_UNKNOWN + 1;     // ShowRaw = retransmit the seiral data to the USB port (value: 1)
-const byte _eOUT_DIST = _eOUT_RAW + 1;        // ShowDist = display distance data (value: 2)
-const byte _eOUT_ANGLE = _eOUT_DIST + 1;      // ShowAngle = display angle data (value: 3)
-const byte _eOUT_MAX = _eOUT_ANGLE + 1;       // WARNING: This value must fit in 8 bits (range: 0-255) (value: 4)
+const byte _eOUT_ANGLE = _eOUT_RAW + 1;       // ShowAngle = display angle data (value: 2)
+const byte _eOUT_MAX = _eOUT_ANGLE + 1;       // WARNING: This value must fit in 8 bits (range: 0-255) (value: 3)
 /*
  * An enumerated list of special output requirements, e.g., Show Errors, Show RPM, Show Interval, Show CSV format
  * NOTE: These are bit-values, so they can be individually set/cleared individually
@@ -264,7 +268,7 @@
 uint16_t motor_rph = 0;
 uint16_t startingAngle = 0;                      // the first scan angle (of group of 4, based on 'index'), in degrees (0..359)
 int iCurrentAngle = 0;
-SerialCommand sCmd;                              // an instance of the serial device handler
+SerialCommand sCmd;                              // create an instance of the serial device handler object

 const int ledPin = 11;                           // blink the LED
 boolean ledState = LOW;                          // Toggle LOW/HIGH
@@ -276,14 +280,18 @@
 void setup() {
   Serial.begin(115200);                           // USB serial
   // Software consistency checks (catchable programmer mistakes)
-  if ((_eOUT_MAX != 4) || (_eOUT_MAX > _MASK_BYTE)) { // limit decimal value to what will fit in 1 byte
+  if ((_eOUT_MAX != 3) || (_eOUT_MAX > _MASK_BYTE)) { // limit decimal value to what will fit in 1 byte
     Serial.println(F("SOFTWARE ERROR: _eOUT_MAX invalid. HALT!"));
     while (1);                                     // HANG!!!!!!
   }
   if (_eSHOW_MAX >= _BITS_PER_BYTE) {              // limit binary value to what can be expressed in 8-bits
     Serial.println(F("SOFTWARE ERROR: _eSHOW_MAX invalid. HALT!"));
     while (1);                                     // HANG!!!!
-  }
+  }
+  if (_EEPROM_Config_LEN >= _EEPROM_SIZE) {
+    Serial.println(F("SOFTWARE ERROR: _EEPROM_Config_LEN >= _EEPROM_SIZE. HALT!"));
+    while (1);                                     // HANG!!!!
+  }
   EEPROM_readAnything(_EE_OFFSET_ID, xv_config);   // read the saved EEPROM configuration
   if(xv_config.id != _EEPROM_ID) {                 // If EEPROM ID has changed...
     Serial.println(F("EEPROM version is different from last time. Initializing EEPROM"));
@@ -297,7 +305,7 @@
   rpmPID.SetSampleTime(xv_config.sample_time);
   rpmPID.SetTunings(xv_config.Kp, xv_config.Ki, xv_config.Kd);
   rpmPID.SetMode(AUTOMATIC);
-  initSerialCommands();                             // Add commands to te 'sCmd' object
+  initSerialCommands();                            // Add commands to te 'sCmd' object
   pinMode(ledPin, OUTPUT);
   eState = _eState_Find_COMMAND;                   // Initialize the 'state' for the main loop
   for (ixPacket = 0; ixPacket < _PACKET_LENGTH; ixPacket++)  // Initialize
@@ -306,7 +314,7 @@
   if (xv_config.bMotorEnable == false)             // Turn on the motor
     forceMotorOn();                                // enable the motor
   forceRaw();                                      // Default mode = 'show raw data'
-  //hideRaw();                                     // DSH ONLY!!!!!!!!!!!!
+  hideRaw();                                       // DSH ONLY!!!!!!!!!!!!
 }

 // Main loop (forever)
@@ -341,12 +349,11 @@
               processSignalStrength(ix);
             } // if (aryInvalidDataFlag[ix] == 0)
           } // for (int ix = 0; ix < _N_DATA_QUADS; ix++)
-          switch (eShow) {
-            case _eOUT_UNKNOWN :                                // eShow = Unknown or uninitialized (value: 0)
-              break;
-            case _eOUT_DIST :                                   // eShow = display distance data (value: 2)
+          switch (eShow) {
+            //case _eOUT_DIST :                                   // eShow = display distance data
               //break;
-            case _eOUT_ANGLE :                                  // eShow = display angle data (value: 3)
+            case _eOUT_UNKNOWN :                                // eShow = Unknown or uninitialized
+            case _eOUT_ANGLE :                                  // eShow = display angle data
               for (int ix = 0; ix < _N_DATA_QUADS; ix++) {
                 // We can't count on being able to display speed data at angle = 0
                 // so we look for the angle to go from a high value to a lower value
@@ -359,40 +366,44 @@
                 oldAngle = iCurrentAngle;
                 if (xv_config.aryAngles[startingAngle + ix]) {  // if we're supposed to display that angle
                   if (aryInvalidDataFlag[ix] == 0) {            // make sure that the 'Invalid Data' flag is clear
-                    if (xv_config.eOUT & _OUT_MOD_SHOW_CSV) {   // Display in CSV format?
-                      Serial.print(startingAngle + ix);
-                      Serial.print(F(","));
-                      Serial.print(int(aryDist[ix]));
-                      Serial.print(F(","));
-                      Serial.println(aryQuality[ix]);
-                    }
-                    else {
-                      Serial.print(startingAngle + ix);
-                      Serial.print(F(": "));
-                      Serial.print(int(aryDist[ix]));
-                      Serial.print(F(" ("));
-                      Serial.print(aryQuality[ix]);
-                      Serial.println(F(")"));
-                    }
+                    if (eShow == _eOUT_ANGLE) {                 // only display this stuff if we're specifically displaying angles
+                      if (xv_config.eOUT & _OUT_MOD_SHOW_CSV) {   // Display in CSV format?
+                        Serial.print(startingAngle + ix);
+                        Serial.print(F(","));
+                        Serial.print(int(aryDist[ix]));
+                        Serial.print(F(","));
+                        Serial.println(aryQuality[ix]);
+                      }
+                      else {
+                        Serial.print(startingAngle + ix);
+                        Serial.print(F(": "));
+                        Serial.print(int(aryDist[ix]));
+                        Serial.print(F(" ("));
+                        Serial.print(aryQuality[ix]);
+                        Serial.println(F(")"));
+                      }
+                    } // if (eShow == _eOUT_ANGLE)
                   } // if (aryInvalidDataFlag[ix] == 0)
                   else if (xv_config.eOUT & _OUT_MOD_SHOW_ERRORS) { // If we're supposed to show errors...
                     if (xv_config.bMotorEnable) {                   // and if the motor is spinning...
-                      if (xv_config.eOUT & _OUT_MOD_SHOW_CSV) {     // Display in CSV format?
-                        Serial.print(startingAngle + ix);
-                        Serial.print(F(","));
-                        if (aryInvalidDataFlag[ix] & _INVALID_DATA_FLAG)
-                          Serial.println(F("I,"));
-                        if (aryInvalidDataFlag[ix] & _STRENGTH_WARNING_FLAG)
-                          Serial.println(F("S,"));
-                      }
-                      else {                                        // display in normal format
-                        Serial.print(startingAngle + ix);
-                        Serial.print(F(": "));
-                        if (aryInvalidDataFlag[ix] & _INVALID_DATA_FLAG)
-                          Serial.println(F("{I}"));
-                        if (aryInvalidDataFlag[ix] & _STRENGTH_WARNING_FLAG)
-                          Serial.println(F("{S}"));
-                      }
+                      if (eShow == _eOUT_ANGLE) {                 // only display this stuff if we're specifically displaying angles
+                        if (xv_config.eOUT & _OUT_MOD_SHOW_CSV) {     // Display in CSV format?
+                          Serial.print(startingAngle + ix);
+                          Serial.print(F(","));
+                          if (aryInvalidDataFlag[ix] & _INVALID_DATA_FLAG)
+                            Serial.println(F("I,"));
+                          if (aryInvalidDataFlag[ix] & _STRENGTH_WARNING_FLAG)
+                            Serial.println(F("S,"));
+                        }
+                        else {                                        // display in normal format
+                          Serial.print(startingAngle + ix);
+                          Serial.print(F(": "));
+                          if (aryInvalidDataFlag[ix] & _INVALID_DATA_FLAG)
+                            Serial.println(F("{I}"));
+                          if (aryInvalidDataFlag[ix] & _STRENGTH_WARNING_FLAG)
+                            Serial.println(F("{S}"));
+                        }
+                      } // if (eShow == _eOUT_ANGLE)
                     } // if (xv_config.bMotorEnable)
                   }  // else if (xv_config.eOUT & _OUT_MOD_SHOW_ERRORS)
                 }  // if (xv_config.aryAngles[startingAngle + ix])
@@ -465,7 +476,7 @@
       ledState = HIGH;
     }
     digitalWrite(ledPin, ledState);
-    if (((xv_config.eOUT & _MASK_eOUT_SHOW) == _eOUT_DIST)
+    if (((xv_config.eOUT & _MASK_eOUT_SHOW) == _eOUT_UNKNOWN)
      || ((xv_config.eOUT & _MASK_eOUT_SHOW) == _eOUT_ANGLE)) {
       curMillis = millis();
       if (xv_config.eOUT & _OUT_MOD_SHOW_INTERVAL) {
@@ -650,7 +661,6 @@
  * initSerialCommands - add operator commands to the 'sCmd' object
  */
 void initSerialCommands() {
-  sCmd.addCommand("help",       help);
   sCmd.addCommand("Help",       help);
   sCmd.addCommand("ShowConfig",  showConfig);
   sCmd.addCommand("SaveConfig", saveConfig);
@@ -662,8 +672,6 @@
   sCmd.addCommand("SetSampleTime", setSampleTime);
   sCmd.addCommand("ShowRPM",  showRPM);
   sCmd.addCommand("HideRPM",  hideRPM);
-  //sCmd.addCommand("ShowDist",  showDist);                           // REMOVED because functionality is like showAngle(s) - DSH
-  sCmd.addCommand("HideDist",  hideDist);
   sCmd.addCommand("ShowAngles",  showAngles);
   sCmd.addCommand("HideAngles",  hideDist);
   sCmd.addCommand("ShowAngle",  showAngles);
@@ -680,64 +688,31 @@
   sCmd.addCommand("HideCSV", hideCSV);
   sCmd.addCommand("ShowInterval", showInterval);
   sCmd.addCommand("HideInterval", hideInterval);
-}
-/*
- * showDist - Show distance data from LIDAR
- * NOTE: If no angles are set in 'aryAngles', then set them all to 'true'
- *       else, use what's already specified
- */
-void showDist() {
-  unsigned int current_eOUT = xv_config.eOUT;  // save the current value so we can restore the top 8-bits (modifiers)
-  unsigned int currentCommand = current_eOUT & _MASK_eOUT_SHOW; // isolate the command (bottom 8-bits)
-  boolean bAnyAnglesSet;
-
-  if (currentCommand == _eOUT_DIST)                         // we're already showing distance, so just return
-    return;  // xxxxxxx  IS THIS THE RIGHT DECISION?????????!!!!!!!
-  if ((currentCommand == _eOUT_UNKNOWN)
-   || (currentCommand == _eOUT_RAW)
-   || (currentCommand == _eOUT_ANGLE)) {
-    xv_config.eOUT = _eOUT_DIST;                            // set "What we're displaying" to "Distance" & clear top 8-bits
-    xv_config.eOUT |= (current_eOUT & _MASK_eOUT_MODIFIER); // restore any modifier bits
-    EEPROM_writeAnything(_EE_OFFSET_eOUT, xv_config.eOUT);
-    bAnyAnglesSet = false;
-    if (xv_config.bShowAllAngles)                           // at least 1 angle is set
-      bAnyAnglesSet = true;
-    else {
-      bAnyAnglesSet = false;
-      for (int ix = 0; ix < _N_ANGLES; ix++) {
-        if (xv_config.aryAngles[ix]) {
-          bAnyAnglesSet = true;                             // at least 1 angle is set
-          break;
-        }
-      } // for (int ix = 0; ix < _N_ANGLES; ix++)
-      if (bAnyAnglesSet == false) {                         // no angles are set...default to "ALL"
-        for (int ix = 0; ix < _N_ANGLES; ix++)
-          xv_config.aryAngles[ix] = true;
-        EEPROM_writeAnything(_EE_OFFSET_aryAngles, xv_config.aryAngles);
-        xv_config.bShowAllAngles = true;                  // Set 'show_angle' default
-        EEPROM_writeAnything(_EE_OFFSET_SHOW_ALL_ANGLES, xv_config.bShowAllAngles);
-      }
-    } // if not (xv_config.bShowAllAngles)
-    Serial.println(F(" "));
-    Serial.println(F("Showing Distance data <Angle>: <dist mm> (signal strength)}"));
-    if (!(xv_config.bMotorEnable))                          // Turn the motor ON if it's OFF
-      forceMotorOn();
-    }
-  else if (currentCommand == _eOUT_DIST) {
-    //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-    }
-  else {
-    Serial.println(F(" "));
-    Serial.println(F("INTERNAL ERROR @showDist - HALT"));   // someone (probably you) added a value to _eOUT_xxx values!!
-    while (1);                               // HANG!!!
-  }
+  sCmd.addCommand("ShowAll", showAll);
+  sCmd.addCommand("HideAll", hideAll);
+}
+/*
+ * showAll - enable all the display modifier commands, i.e., RPM, Errors, Interval
+ */
+void showAll() {
+  showRPM();                                        // enable showRPM
+  showErrors();                                     // enable showErrors
+  showInterval();                                   // enable showInterval
+}
+/*
+ * hideAll - disable all the display modifier commands, i.e., RPM, Errors, Interval
+ */
+void hideAll() {
+  hideRPM();                                        // disable showRPM
+  hideErrors();                                     // disable showErrors
+  hideInterval();                                   // disable showInterval
 }
 /*
  * hideDist - Hide distance data from LIDAR
  */
 void hideDist() {
   int eShow = (xv_config.eOUT & _MASK_eOUT_SHOW);
-  if ((eShow == _eOUT_DIST) || (eShow == _eOUT_ANGLE)) {    // you can only hide distance if it is currently active
+  if (eShow == _eOUT_ANGLE) {                               // you can only hide distance if it is currently active
     xv_config.eOUT &= -1 - _MASK_eOUT_SHOW;                 // keep top 8-bits and turn off bottom 8 bits before setting command
     xv_config.eOUT |= _eOUT_UNKNOWN;                        // set "What we're displaying" to "unknown"
     EEPROM_writeAnything(_EE_OFFSET_eOUT, xv_config.eOUT);
@@ -1257,7 +1232,8 @@

   Serial.println(F(" "));
   Serial.println(F(" "));
-
+  Serial.println(F("NOTE: All commands are case-insensitive"));
+  Serial.println(F(" "));
   Serial.println(F("What to display:"));
   Serial.println(F("  ShowRaw       - Enable the output of the raw LIDAR data (default)"));
   Serial.println(F("  HideRaw       - Stop outputting the raw data from the LIDAR"));
@@ -1267,14 +1243,16 @@
   Serial.println(F("  HideAngle(s)  - Hide distance data for all angles"));
   Serial.println(F(" "));
   Serial.println(F("Display modifiers:"));
+  Serial.println(F("  ShowAll       - Show Errors + Interval + RPM"));
+  Serial.println(F("  HideAll       - Suppress Errors + Interval + RPM"));
   Serial.println(F("  ShowError(s)  - Show all error messages"));
   Serial.println(F("  HideError(s)  - Hide error messages"));
   Serial.println(F("  ShowInterval  - Show time interval per revolution in ms"));
   Serial.println(F("  HideInterval  - Hide time interval"));
+  Serial.println(F("  ShowRPM       - Show the motor speed (RPM)"));
+  Serial.println(F("  HideRPM       - Hide the motor speed"));
   Serial.println(F("  ShowCSV       - Show data in comma-separated variable (.csv) format"));
   Serial.println(F("  HideCSV       - Hide csv format"));
-  Serial.println(F("  ShowRPM       - Show the motor speed (RPM)"));
-  Serial.println(F("  HideRPM       - Hide the motor speed"));
   Serial.println(F(" "));
   Serial.println(F("Other commands:"));
   Serial.println(F("  MotorOff      - Stop spinning the LIDAR"));
@@ -1374,9 +1352,6 @@
     case _eOUT_RAW :
       Serial.println(F("Show Raw Data"));
       break;
-    case _eOUT_DIST :
-      Serial.println(F("Show Distance data"));
-      break;
     case _eOUT_ANGLE :
       Serial.println(F("Show Angle"));
       break;


remove old FSRtest

remove old FSRtest

--- FSR_test.ino
+++ FSR_test.ino
@@ -1,71 +0,0 @@
-/*
-  Analog input, analog output, serial output
-
- Reads an analog input pin, maps the result to a range from 0 to 255
- and uses the result to set the pulsewidth modulation (PWM) of an output pin.
- Also prints the results to the serial monitor.
-
- The circuit:
- * potentiometer connected to analog pin 0.
-   Center pin of the potentiometer goes to the analog pin.
-   side pins of the potentiometer go to +5V and ground
- * LED connected from digital pin 9 to ground
-
- created 29 Dec. 2008
- modified 9 Apr 2012
- by Tom Igoe
-
- This example code is in the public domain.
-
- */
-
-// These constants won't change.  They're used to give names
-// to the pins used:
-const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to
-//const int analogOutPin = 9; // Analog output pin that the LED is attached to
-
-int sensorValue = 0;        // value read from the pot
-float outputValue = 0.0;        // value output to the PWM (analog out)
-int count = 0;
-int sum = 0;
-int threshold = 0;
-
-void setup() {
-  // initialize serial communications at 9600 bps:
-  Serial.begin(9600);
-  threshold = analogRead(analogInPin);
-}
-
-void loop() {
-  // read the analog in value:
-  // map it to the range of the analog out:
-  sensorValue = analogRead(analogInPin);
-  sensorValue = (float)sensorValue;
-  threshold = (float)threshold;
-
-  outputValue = (sensorValue-threshold)/150.0;
-  // change the analog out value:
-  //analogWrite(analogOutPin, outputValue);
-
-  // print the results to the serial monitor:
-
-  Serial.print("sensor = ");
-  Serial.print(sensorValue);
-  Serial.print("\t");
-  Serial.println(outputValue);
-  count++;
-  sum+=sensorValue;
-  if(count>100){
-    Serial.println(sum/count);
-    count=0;
-    sum=0;
-  }
-
-  //Serial.print("\t output = ");
-  //Serial.println(outputValue);
-
-  // wait 2 milliseconds before the next loop
-  // for the analog-to-digital converter to settle
-  // after the last reading:
-  delay(30);
-}


Added settings for the Adafruit Gemma

Added settings for the Adafruit Gemma

--- PulseSensorAmped_Arduino_1dot4/Timer_Interrupt_Notes.ino
+++ PulseSensorAmped_Arduino_1dot4/Timer_Interrupt_Notes.ino
@@ -130,7 +130,7 @@

   ******************************************************************************************
-  ARDUINO Flora, Fio v3 (or any other board with ATmega32u4 running at 8MHz)
+  ADAFRUIT Flora, ARDUINO Fio v3 (or any other board with ATmega32u4 running at 8MHz)

   >> Timer1

@@ -149,9 +149,24 @@
       ISR(TIMER1_COMPA_vect)

   ******************************************************************************************
-
-
-
+  ADAFRUIT Gemma (or any other board with ATtiny85 running at 8MHz)
+
+  Timer1
+
+    Use of Timer1 breaks PWM output on pin D1
+
+      void interruptSetup(){
+        TCCR1 = 0x88;      // Clear Timer on Compare, Set Prescaler to 128 TEST VALUE
+        GTCCR &= 0x81;     // Disable PWM, don't connect pins to events
+        OCR1C = 0x7C;      // Set the top of the count to  124 TEST VALUE
+        OCR1A = 0x7C;      // Set the timer to interrupt after counting to TEST VALUE
+        bitSet(TIMSK,6);   // Enable interrupt on match between TCNT1 and OCR1A
+        sei();             // Enable global interrupts
+      }
+
+    The only other thing you will need is the correct ISR vector in the next step.
+
+      ISR(TIMER1_COMPA_vect)

   ******************************************************************************************


serial messenger bug fixes

serial messenger bug fixes

--- examples/AFSK_SerialMessenger/AFSK_SerialMessenger.ino
+++ examples/AFSK_SerialMessenger/AFSK_SerialMessenger.ino
@@ -12,7 +12,7 @@
  * To send a message: connect to the Arduino over a Serial link.
  * Send the following over the serial link:
  * `from,to,:message
- * example: * `KG7OGM,KG7OGM,:Hi there
+ * example: * KG7OGM,KG7OGM,:Hi there`
  */

@@ -140,6 +140,7 @@
   }
   Serial.println("Done sending");
   radio.setModeReceive();
+  messagebuff = "";
 }


TODO -> Done

TODO -> Done

--- octotemp/code/OctoTemp/OctoTemp/OctoTemp.ino
+++ octotemp/code/OctoTemp/OctoTemp/OctoTemp.ino
@@ -167,8 +167,6 @@
   return TempC(channel) * 1.8 + 32;
 }

-// TODO(z2amiller):  Do something interesting with this data.
-//                   Post to prometheus or MQTT or something.
 void loop(void)
 {
   MapMetric met = MapMetric("octo_sensor_tempF", "location");


test code

test code

--- src/main.ino
+++ src/main.ino
@@ -20,9 +20,10 @@

 // LOOP //
 void loop() {
-  m1.write(90);
-  int val = m1.read();
-  Serial.println(val);
+  m1.write(0);
+  delay(500);
+  m1.write(180);
+  delay(500);
 }


Updated and commented example

Updated and commented example

--- examples/ArtnetReceiveCallback/ArtnetReceiveCallback.ino
+++ examples/ArtnetReceiveCallback/ArtnetReceiveCallback.ino
@@ -1,25 +1,29 @@
-// This #include statement was automatically added by the Particle IDE.
+/*
+This is similar to ArtnetReceive but uses a callback to read the data.
+This example may be copied under the terms of the MIT license, see the LICENSE file for details
+*/
+
 #include "Artnet/Artnet.h"

 Artnet artnet;

 void setup() {
     Serial.begin(9600);
-
+
+	// Start listening for Art-Net packages
+	// Call onDmxFrame when receiving one
     artnet.begin();
     artnet.setArtDmxCallback(onDmxFrame);
-
-    pinMode(D7, OUTPUT);
-    digitalWrite(D7, HIGH);
 }

 void loop() {
+	// Process pending Art-Net packages
     artnet.read();
 }

 void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data)
 {
-  // print out our data
+  // Print out the data received
   Serial.print("universe number = ");
   Serial.print(universe);
   Serial.print("\tdata length = ");
@@ -34,6 +38,4 @@
   }
   Serial.println();
   Serial.println();
-
-    digitalWrite(D7, data[0] != 0);
 }


Undoing example change.

Undoing example change.

--- examples/Fire2012/Fire2012.ino
+++ examples/Fire2012/Fire2012.ino
@@ -1,9 +1,8 @@
-#define FASTLED_ALLOW_INTERRUPTS 1
 #include <FastLED.h>

 #define LED_PIN     5
 #define COLOR_ORDER GRB
-#define CHIPSET     WS2811_400
+#define CHIPSET     WS2811
 #define NUM_LEDS    30

 #define BRIGHTNESS  200


Update example

Update example

--- examples/hdc1000.ino
+++ examples/hdc1000.ino
@@ -5,14 +5,27 @@

 void setup() {
   Serial.begin(9600);
+  // hdc1000.setRdyPin(PIN_NO); // use Rdy Pin
   hdc1000.begin();
 }

 void loop() {
   float temp = hdc1000.getTemperature();
+
+  if (temp == HDC1000_ERROR_CODE) {
+    hdc1000.begin(); // retry once
+    temp = hdc1000.getTemperature();
+  }
   Serial.print("Temperature: ");
   Serial.println(temp);
+
   float humi = hdc1000.getHumidity();
+
+  if (humi== HDC1000_ERROR_CODE) {
+    hdc1000.begin(); // retry once
+    humi = hdc1000.getTemperature();
+  }
+
   Serial.print("Humidity: ");
   Serial.println(humi);
   delay(1000);


Reading capacitive values

Reading capacitive values

--- Watering/Watering.ino
+++ Watering/Watering.ino
@@ -1,7 +1,10 @@
+#include <CapacitiveSensor.h>
+
 const int gatePin = 11;
 const int tempPin = A0;
 const int lightPin = A1;
 int mode, tempVal, outputValue;
+CapacitiveSensor capSensor = CapacitiveSensor(4, 2);

 void setup() {
   Serial.begin(9600);
@@ -27,6 +30,8 @@
   readTemp();
   delay(10);
   readLight();
+  delay(10);
+  readTouch();
   delay(500);
 }

@@ -51,3 +56,9 @@
   Serial.println(tempVal);
 }

+void readTouch() {
+  tempVal = capSensor.capacitiveSensor(30);
+  Serial.print("Cap value: ");
+  Serial.println(tempVal);
+}
+


mas correcciones,, gomen

mas correcciones,, gomen

--- ARDUINO/sleep_example_routine_temp_light/sleep_example_routine_temp_light.ino
+++ ARDUINO/sleep_example_routine_temp_light/sleep_example_routine_temp_light.ino
@@ -47,7 +47,7 @@
    delay(2000);                   //tiempo de espera
    t_aux=analogRead(T_PIN);       //lectura de T analogica 0-1023

-   Tmp = 5*100*t_aux/1024; //10mV -> 1 ºC, con eso escalamos
+   Tmp = 5*100*t_aux/1023; //10mV -> 1 ºC, con eso escalamos

   //COM: puerto serie de los datos de T
   Serial.print("Temperature: ");


LIGHT Example

LIGHT Example

--- examples/Unit/LIGHT/LIGHT.ino
+++ examples/Unit/LIGHT/LIGHT.ino
@@ -7,31 +7,37 @@
 * 获取更多资料请访问：https://docs.m5stack.com/zh_CN/core/gray
 *
 * describe: Light.  环境光传感器
-* date：2021/8/18
+* date：2022/2/13
 *******************************************************************************
-  Please connect to Port B,Use the Light Unit screen to display the current ambient lighting value
-  请连接端口 B ,使用Light Unit 屏幕显示当前环境光照值。
+  Please connect to Port B,Use the Light Unit screen to display the current
+ambient lighting value 请连接端口 B ,使用Light Unit 屏幕显示当前环境光照值。
 */

 #include <M5Stack.h>

+TFT_eSprite img = TFT_eSprite(&M5.Lcd);
+
 void setup() {
-  M5.begin(); //Init M5Stack.  初始化M5Stack
-  M5.Power.begin(); //Init power  初始化电源模块
-  M5.lcd.setTextSize(2);  //Set the text size to 2.  设置文字大小为2
-  M5.Lcd.printf("UNIT_LIGHT EXAMPLE\n\n");
-  M5.Lcd.println("Analog:");
-  M5.Lcd.println("Digital:");
-  pinMode(26, INPUT); //Set pin 26 as input mode.  设置引脚26为输入模式
+    M5.begin();        // Init M5Stack.  初始化M5Stack
+    M5.Power.begin();  // Init power  初始化电源模块
+    img.setColorDepth(8);
+    img.createSprite(320, 240);  //创建一块320x240的画布
+    img.setTextSize(2);
+    pinMode(26, INPUT);  // Set pin 26 as input mode.  设置引脚26为输入模式
 }

 void loop() {
-  static uint16_t digitalRead_value = 0, analogRead_value = 0;
-  analogRead_value = analogRead(36);  //Store the analog quantity read from pin 36.  将36号引脚读取到的模拟量存储
-  digitalRead_value = digitalRead(26);  //Store the number read from pin 26.  将26号引脚读取到的数字量存储
-  M5.Lcd.setCursor(90, 30);
-  M5.Lcd.printf("%d\n", analogRead_value);
-  M5.Lcd.setCursor(90, 50);
-  M5.Lcd.printf("%d\n", digitalRead_value);
-  delay(10);
+    static uint16_t digitalRead_value = 0, analogRead_value = 0;
+    analogRead_value = analogRead(36);  // Store the analog quantity read from
+                                        // pin 36. 将36号引脚读取到的模拟量存储
+    digitalRead_value = digitalRead(
+        26);  // Store the number read from pin 26. 将26号引脚读取到的数字量存储
+    img.fillRect(0, 0, 320, 240, 0x00);
+    img.drawString("UNIT_LIGHT EXAMPLE", 40, 0);
+    img.setCursor(90, 30);
+    img.printf("Analog:%d\n", analogRead_value);
+    img.setCursor(90, 50);
+    img.printf("Digital:%d\n", digitalRead_value);
+    img.pushSprite(0, 0);  //把画布推送到屏幕(0,0)处
+    delay(10);
 }


Replaced some '#define' with 'const'.

Replaced some '#define' with 'const'.

Some color and text arranged on tft.

--- tfttask.ino
+++ tfttask.ino
@@ -1,36 +1,24 @@
-#define TEXT_COLOR    ILI9341_YELLOW
-#define BACK_COLOR    ILI9341_BLACK
-
 void tftTask( void * pvParameters )
 {
   while (1)
   {
-    tft.setTextColor( TEXT_COLOR , BACK_COLOR );
-    tft.setCursor( 15, 0 );
-    tft.setTextSize( 2 );
+    const uint16_t TFT_TEXT_COLOR   = ILI9341_YELLOW;
+    const uint16_t TFT_DATE_COLOR   = ILI9341_BLUE;
+    const uint16_t TFT_TEMP_COLOR   = ILI9341_WHITE;
+    const uint16_t TFT_BACK_COLOR   = ILI9341_BLACK;

-    struct tm timeinfo;
-    if ( !getLocalTime( &timeinfo ) )
-    {
-      tft.println( "Failed to obtain time" );
-    }
-    else
-    {
-      tft.println( asctime( &timeinfo ) );
-    }
-
-#define BARS_BOTTOM    170
-#define BARS_HEIGHT    150
-#define BARS_BORDER    10
-#define BARS_WIDTH     ILI9341_TFTHEIGHT / 5
-#define HEIGHT_FACTOR  BARS_HEIGHT / 100.0
+    const uint16_t BARS_BOTTOM      = 181;
+    const uint16_t BARS_HEIGHT      = 180;
+    const uint16_t BARS_BORDER      = 10;
+    const uint16_t BARS_WIDTH       = ILI9341_TFTHEIGHT / 5;
+    const float    HEIGHT_FACTOR    = BARS_HEIGHT / 100.0;

     for ( byte thisChannel = 0; thisChannel < NUMBER_OF_CHANNELS; thisChannel++ )
     {
       //convert from String to RGB color
       //https://stackoverflow.com/questions/2342114/extracting-rgb-color-components-from-integer-value/2342149#2342149
       int r, g, b;
-      int color = strtol( &channel[thisChannel].color[1], NULL, 16 );
+      uint32_t color = strtol( &channel[thisChannel].color[1], NULL, 16 );
       r = ( color & 0xFF0000 ) >> 16; // Filter the 'red' bits from color. Then shift right by 16 bits.
       g = ( color & 0x00FF00 ) >> 8;  // Filter the 'green' bits from color. Then shift right by 8 bits.
       b = ( color & 0x0000FF );       // Filter the 'blue' bits from color. No shift needed.
@@ -40,7 +28,7 @@
                     BARS_BOTTOM - BARS_HEIGHT,
                     BARS_WIDTH - BARS_BORDER * 2,
                     BARS_HEIGHT - channel[thisChannel].currentPercentage * HEIGHT_FACTOR,
-                    BACK_COLOR );
+                    TFT_BACK_COLOR );
 /*
       //high water mark
       tft.drawFastHLine( thisChannel * BARS_WIDTH + BARS_BORDER,
@@ -53,8 +41,11 @@
                     BARS_WIDTH - BARS_BORDER * 2,
                     channel[thisChannel].currentPercentage * HEIGHT_FACTOR,
                     tft.color565( r, g, b ) );
+
+      tft.setCursor( thisChannel * BARS_WIDTH + 12, BARS_BOTTOM + 4 );
       tft.setTextSize( 1 );
-      tft.setCursor( thisChannel * BARS_WIDTH + 10, BARS_BOTTOM + 4 );
+      tft.setTextColor( TFT_TEXT_COLOR , TFT_BACK_COLOR );
+
       char buffer [9];
       snprintf( buffer, sizeof( buffer ), "%*" ".2f%%", 6, channel[thisChannel].currentPercentage );
       tft.print( buffer );
@@ -62,14 +53,28 @@

     tft.setCursor( 0, BARS_BOTTOM + 20 );
     tft.setTextSize( 2 );
+    tft.setTextColor( TFT_TEMP_COLOR , TFT_BACK_COLOR );
+
     if ( numberOfFoundSensors )
     {
       for ( byte thisSensor = 1; thisSensor <= numberOfFoundSensors; thisSensor++ )
       {
-        tft.print( " " + String( sensor[thisSensor].temp / 16.0 ) + "C " );
+        tft.print( " " + String( sensor[thisSensor].temp / 16.0 ) + (char)247 + "C " );
       }
     }

+    tft.setCursor( 15, BARS_BOTTOM + 40 );
+    tft.setTextColor( TFT_DATE_COLOR , TFT_BACK_COLOR );
+
+    struct tm timeinfo;
+    if ( !getLocalTime( &timeinfo ) )
+    {
+      tft.println( "Failed to obtain time" );
+    }
+    else
+    {
+      tft.println( asctime( &timeinfo ) );
+    }
     vTaskDelay( 500 / portTICK_PERIOD_MS );
   }
 }


it's working

it's working

--- arduino/arduino.ino
+++ arduino/arduino.ino
@@ -23,6 +23,7 @@
 byte mac[] = {
   0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
 };
+
 IPAddress ip(192, 168, 2, 15);

 // Google DNS
@@ -33,13 +34,12 @@
 // (port 80 is default for HTTP):
 // EthernetServer server(80);

-//
-char serverName[] = "smart-trash.app.hackinpoa.tsuru.io";    // name address for Google (using DNS)
+char serverName[] = "smart-trash.app.hackinpoa.tsuru.io";

 EthernetClient sendClient;

 unsigned long lastConnectionTime = 0;             // last time you connected to the server, in milliseconds
-const unsigned long postingInterval = 1L * 1000L; // Every second (10000)
+const unsigned long postingInterval = 10L * 1000L; // Every second (10000)

 String postData;

@@ -133,6 +133,8 @@

 // this method makes a HTTP connection to the server:
 void httpRequest(int sensor, int value) {
+  Serial.println("sending...");
+
   // close any connection before send a new request.
   // This will free the socket on the WiFi shield
   sendClient.stop();
@@ -140,8 +142,9 @@
   String path = "/coleta/" + String(sensor) + "/" + String(value);

   // if there's a successful connection:
-  if (sendClient.connect(serverName, 80)) {
-    Serial.println("connecting...");
+  int connected = sendClient.connect(serverName, 80);
+  if (connected) {
+    Serial.println("connected");
     // send the HTTP PUT request:
     sendClient.println("GET " + path + " HTTP/1.1");
     sendClient.println("Host: smart-trash.app.hackinpoa.tsuru.io");
@@ -149,19 +152,23 @@
     sendClient.println("Connection: close");
     sendClient.println();

+    Serial.println("sent");
+
     //sendClient.print("Content-Length: ");
     //sendClient.println(postData.length());
     //sendClient.println();
     //sendClient.println(postData);
-
-    sendClient.println();
+    // sendClient.println();

     // note the time that the connection was made:
     lastConnectionTime = millis();
+
+    // give time to se
+    //delay(1);
   }
   else {
     // if you couldn't make a connection:
-    Serial.println("connection failed");
+    Serial.println("connection failed" + String(connected));
   }
 }


Update pin_change_interrupt.ino

Update pin_change_interrupt.ino

--- interrupts/pin_change_interrupt.ino
+++ interrupts/pin_change_interrupt.ino
@@ -7,6 +7,9 @@

 James H. Bannock, 2017
 Norges teknisk-naturvitenskapelige universitet (NTNU)
+
+In this example a message is written to the serial port each time a state change
+on a button is detected (rising- and falling-edge detection).

 Notes:
   - A button is attached to Pin 9 and GND


4 motors drive

4 motors drive

--- dayrider/dayrider.ino
+++ dayrider/dayrider.ino
@@ -3,10 +3,11 @@

 #include <Dagu4Motor.h>

-//YunServer server;
-              // pwn, dir, cur(analog), encA, encB
-Dagu4Motor left(11, 12, 0, 0, 0);
-Dagu4Motor right(3, 2, 0, 0, 0);
+                 // pwm, dir, cur(analog), encA, encB
+Dagu4Motor left_front(5, 4, 0, 0, 0);
+Dagu4Motor left_back(3, 2, 0, 0, 0);
+Dagu4Motor right_front(11, 12, 0, 0, 0);
+Dagu4Motor right_back(9, 8, 0, 0, 0);

 void setup() {
   //Serial.begin(9600);
@@ -15,11 +16,15 @@
   Bridge.begin();
   Mailbox.begin();
   digitalWrite(13, HIGH);
-
-  //Serial.println("Starting Dayrider 0.1");
-
-  left.begin();
-  left.stopMotors();
+
+  left_front.begin();
+  left_front.stopMotors();
+  left_back.begin();
+  left_back.stopMotors();
+  right_front.begin();
+  right_front.stopMotors();
+  right_back.begin();
+  right_back.stopMotors();

 }

@@ -28,18 +33,20 @@
     process_cmd();
   }

-  delay(50);
+  delay(10);
 }

 #define LEFT 1
 #define RIGHT 2
 #define FORWARD 3
 #define BACKWARD 4
+#define FORWARD_LEFT 5
+#define FORWARD_RIGHT 6

 #define MOTOR_FORWARD 0
-#define MOTOR_BACKWARD 1
+#define MOTOR_BACKWARDS 1

-#define MOTOR_SPEED 150
+#define MOTOR_SPEED 100

 int current_direction = 0;

@@ -61,17 +68,37 @@

 }

+void left_motor(int dir, int spd) {
+     left_front.setMotorDirection(dir);
+     left_front.setSpeed(spd);
+     left_back.setMotorDirection(!dir);
+     left_back.setSpeed(spd);
+}
+
+void right_motor(int dir, int spd) {
+     right_front.setMotorDirection(dir);
+     right_front.setSpeed(spd);
+     right_back.setMotorDirection(!dir);
+     right_back.setSpeed(spd);
+}
+
 void turn_left() {
      if (current_direction == RIGHT) {
         stop_movement();
         current_direction = 0;
         return;
-     }
-     left.setMotorDirection(MOTOR_FORWARD);
-     left.setSpeed(MOTOR_SPEED);
-     //right.setMotorDirection(MOTOR_BACKWARD);
-     //right.setSpeed(MOTOR_SPEED / 2);
-     current_direction = LEFT;
+     } else if (current_direction == FORWARD_RIGHT) {
+        go_forward();
+     }
+     if (current_direction == FORWARD) {
+        left_motor(MOTOR_FORWARD, MOTOR_SPEED + 70);
+        right_motor(MOTOR_BACKWARDS, MOTOR_SPEED / 2);
+        current_direction = FORWARD_LEFT;
+     } else {
+        left_motor(MOTOR_FORWARD, MOTOR_SPEED / 2);
+        right_motor(MOTOR_BACKWARDS, MOTOR_SPEED / 2);
+        current_direction = LEFT;
+     }
 }

 void turn_right() {
@@ -79,12 +106,18 @@
         stop_movement();
         current_direction = 0;
         return;
+     } else if (current_direction == FORWARD_LEFT) {
+        go_forward();
      }
-     //right.setMotorDirection(MOTOR_FORWARD);
-     //right.setSpeed(MOTOR_SPEED);
-     left.setMotorDirection(MOTOR_BACKWARD);
-     left.setSpeed(MOTOR_SPEED / 2);
-     current_direction = RIGHT;
+     if (current_direction == FORWARD) {
+        right_motor(MOTOR_FORWARD, MOTOR_SPEED + 70);
+        left_motor(MOTOR_BACKWARDS, MOTOR_SPEED / 2);
+        current_direction = FORWARD_RIGHT;
+     } else {
+        right_motor(MOTOR_FORWARD, MOTOR_SPEED / 2);
+        left_motor(MOTOR_BACKWARDS, MOTOR_SPEED / 2);
+        current_direction = RIGHT;
+     }
 }

 void go_forward() {
@@ -93,10 +126,13 @@
         current_direction = 0;
         return;
      }
-     //right.setMotorDirection(MOTOR_FORWARD);
-     //right.setSpeed(MOTOR_SPEED);
-     left.setMotorDirection(MOTOR_FORWARD);
-     left.setSpeed(MOTOR_SPEED);
+     if (current_direction == FORWARD) {
+         left_motor(MOTOR_FORWARD, MOTOR_SPEED + 100);
+         right_motor(MOTOR_FORWARD, MOTOR_SPEED + 100);
+     } else {
+         left_motor(MOTOR_FORWARD, MOTOR_SPEED);
+         right_motor(MOTOR_FORWARD, MOTOR_SPEED);
+     }
      current_direction = FORWARD;
 }

@@ -106,32 +142,16 @@
         current_direction = 0;
         return;
      }
-     //right.setMotorDirection(MOTOR_BACKWARD);
-     //right.setSpeed(MOTOR_SPEED);
-     left.setMotorDirection(MOTOR_BACKWARD);
-     left.setSpeed(MOTOR_SPEED);
+     left_motor(MOTOR_BACKWARDS, MOTOR_SPEED);
+     right_motor(MOTOR_BACKWARDS, MOTOR_SPEED);
      current_direction = BACKWARD;
 }

 void stop_movement() {
-     //right.setSpeed(0);
-     left.setSpeed(0);
-}
-
-void motorCommand(String side, int dir, int spd) {
-
-  if (side == "left") {
-     left.setMotorDirection(dir);
-     left.setSpeed(spd);
-  } else if (side == "right") {
-     right.setMotorDirection(dir);
-     right.setSpeed(spd);
-  } else if (side == "both") {
-     left.setMotorDirection(dir);
-     left.setSpeed(spd);
-     right.setMotorDirection(dir);
-     right.setSpeed(spd);
-  }
+     right_front.setSpeed(0);
+     right_back.setSpeed(0);
+     left_front.setSpeed(0);
+     left_back.setSpeed(0);
 }


flush serial updated

flush serial updated

--- jenny5-firmware/jenny5-firmware.ino
+++ jenny5-firmware/jenny5-firmware.ino
@@ -45,7 +45,7 @@

 char is_command_running;

-const char* firmware_version = "2019.04.29.0"; // year.month.day.build number
+const char* firmware_version = "2019.04.30.0"; // year.month.day.build number

 #define MAX_BUFFER_LENGTH 65

@@ -63,19 +63,15 @@
 {
 	first_start = 0;

-
 	current_buffer[0] = 0;
-

 	tera_ranger_one_lidar = NULL;

 	Serial.begin(115200); //Open Serial connection
 	while (!Serial);
-	int num_available = Serial.available();
-	if (num_available) {
-		char tmp_str[64];
-		Serial.readBytes(tmp_str, num_available);
-	}
+	while (Serial.available() > 0)
+		char t = Serial.read();
+
 	//Serial.begin(57600); //Open Serial connection

 	//delay(2000);


use dtostrf() to convert floats to strings


removed setPwmFrequency()

removed setPwmFrequency()

--- discont/Motor_Shield/MotorShield/MotorShield.ino
+++ discont/Motor_Shield/MotorShield/MotorShield.ino
@@ -203,66 +203,3 @@
   tickDataLeft--;
   }
 }
-
-/**
- * Divides a given PWM pin frequency by a divisor.
- *
- * The resulting frequency is equal to the base frequency divided by
- * the given divisor:
- *   - Base frequencies:
- *      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
- *      o The base frequency for pins 5 and 6 is 62500 Hz.
- *   - Divisors:
- *      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
- *        256, and 1024.
- *      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
- *        128, 256, and 1024.
- *
- * PWM frequencies are tied together in pairs of pins. If one in a
- * pair is changed, the other is also changed to match:
- *   - Pins 5 and 6 are paired on timer0
- *   - Pins 9 and 10 are paired on timer1
- *   - Pins 3 and 11 are paired on timer2
- *
- * Note that this function will have side effects on anything else
- * that uses timers:
- *   - Changes on pins 3, 5, 6, or 11 may cause the delay() and
- *     millis() functions to stop working. Other timing-related
- *     functions may also be affected.
- *   - Changes on pins 9 or 10 will cause the Servo library to function
- *     incorrectly.
- *
- * Thanks to macegr of the Arduino forums for his documentation of the
- * PWM frequency divisors. His post can be viewed at:
- *   http://forum.arduino.cc/index.php?topic=16612#msg121031
- */
-void setPwmFrequency(int pin, int divisor) {
-  byte mode;
-  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
-  switch(divisor) {
-    case 1: mode = 0x01; break;
-    case 8: mode = 0x02; break;
-    case 64: mode = 0x03; break;
-    case 256: mode = 0x04; break;
-    case 1024: mode = 0x05; break;
-    default: return;
-  }
-  if(pin == 5 || pin == 6) {
-    TCCR0B = TCCR0B & 0b11111000 | mode;
-  } else {
-    TCCR1B = TCCR1B & 0b11111000 | mode;
-  }
-  } else if(pin == 3 || pin == 11) {
-  switch(divisor) {
-    case 1: mode = 0x01; break;
-    case 8: mode = 0x02; break;
-    case 32: mode = 0x03; break;
-    case 64: mode = 0x04; break;
-    case 128: mode = 0x05; break;
-    case 256: mode = 0x06; break;
-    case 1024: mode = 0x07; break;
-    default: return;
-  }
-  TCCR2B = TCCR2B & 0b11111000 | mode;
-  }
-}


updated example demo time string

updated example demo time string

--- examples/heart_matrix_demo/heart_matrix_demo.ino
+++ examples/heart_matrix_demo/heart_matrix_demo.ino
@@ -35,18 +35,18 @@
 unsigned long min_var = 99999999;

 void setup() {
-   Serial.begin(9600);
-   MsTimer2::set(1,displayer2);
-   MsTimer2::start();
-   for (int i = 0 ; i < num_cols; i++) volumes[i] = 8;
-   for (int i = 0 ; i < buffer_size; i++) noises[i] = random(300,612);
-   if(mode == 2) hm.set_message(" Hello I'm the Heart Matrix! ");
-   if(mode == 0) hm.animate();
-
-   Wire.begin();
-   //clock.setDateTime(__DATE__,__TIME__);
+  Serial.begin(9600);
+  MsTimer2::set(1,displayer2);
+  MsTimer2::start();
+  for (int i = 0 ; i < num_cols; i++) volumes[i] = 8;
+  for (int i = 0 ; i < buffer_size; i++) noises[i] = random(300,612);
+  if(mode == 2) hm.set_message(" Hello I'm the Heart Matrix! ");
+  if(mode == 0) hm.animate();
+
+  Wire.begin();
+  clock.setDateTime(__DATE__,__TIME__);
 }
-
+
 void loop() {
   if(mode == 0) sound_display();
   else if(mode == 1) clock_display();
@@ -59,13 +59,13 @@
 }

 void check_buttons(){
- if(digitalRead(9) == HIGH && millis() - last_press > 250){
-   mode = ++mode % num_modes;
-   if(mode == 0) hm.animate();
-   if(mode == 2) hm.set_message(" Hello I'm the Heart Matrix! ");
-   last_press = millis();
- }
- hm.set_scroll_wait(max(20, analogRead(0)/4));
+  if(digitalRead(9) == HIGH && millis() - last_press > 250){
+    mode = ++mode % num_modes;
+    if(mode == 0) hm.animate();
+    if(mode == 2) hm.set_message(" Hello I'm the Heart Matrix! ");
+    last_press = millis();
+  }
+  hm.set_scroll_wait(max(20, analogRead(0)/4));
 }

 void text_display(){
@@ -75,9 +75,9 @@
   hm.on();
   if (millis() - last_update > 1000){
     stime = " ";
-
+
     byte a_hour = clock.hour24();
-    String a_hour_s = String(a_hour,HEX);
+    String a_hour_s = String(a_hour);
     int hour_int = a_hour_s.toInt();
     String ampm = "am  ";
     if (hour_int >= 12){
@@ -90,47 +90,47 @@
     stime += ":";
     byte a_min = clock.minute();
     if (a_min < 10 ) stime += String(0);
-    stime += String(a_min,HEX);
+    stime += String(a_min);
     stime += ":";
     byte a_sec = clock.second();
     if (a_sec < 10 ) stime += String(0);
-    stime += String(a_sec,HEX);
+    stime += String(a_sec);
     hm.set_message(stime+ampm );
     last_update = millis();
   }
 }

 void sound_display(){
-   // Get a value from the electret microphone
-   noises[cur_index] = analogRead(mic_pin) ;
-   cur_index++;
-   if(cur_index == buffer_size) cur_index = 0;
-   // Control the scroll speed with a potentiometer on analog pin 0
-   delay_speed = max(10, (analogRead(0)/4));
-
-   // Shift the waveform over one column
-   if (millis() - last_shift > delay_speed){
-     last_shift = millis();
-     unsigned int avg = average(noises, buffer_size);
-     unsigned long var = variance(noises, buffer_size);
-     max_var = max(var, max_var);
-     min_var = min(var, min_var);
-     var = map(var,min_var , max_var, 0, 9);
-     for (int i = 1 ; i < num_cols; i++){
+  // Get a value from the electret microphone
+  noises[cur_index] = analogRead(mic_pin) ;
+  cur_index++;
+  if(cur_index == buffer_size) cur_index = 0;
+  // Control the scroll speed with a potentiometer on analog pin 0
+  delay_speed = max(10, (analogRead(0)/4));
+
+  // Shift the waveform over one column
+  if (millis() - last_shift > delay_speed){
+    last_shift = millis();
+    unsigned int avg = average(noises, buffer_size);
+    unsigned long var = variance(noises, buffer_size);
+    max_var = max(var, max_var);
+    min_var = min(var, min_var);
+    var = map(var,min_var , max_var, 0, 9);
+    for (int i = 1 ; i < num_cols; i++){
       volumes[i-1] = volumes[i];
-     }
-     volumes[num_cols-1] = var;
-   }
-
-   // Write the wave form to LED display
-   for (int i = 0 ; i < num_cols; i++){
-     for (int j = 0 ; j < volumes[i]; j++){
-       hm.set_pixel(i, j, true);
-     }
-     for (int j = volumes[i] ; j < 8; j++){
-       hm.set_pixel(i, j, false);
-     }
-   }
+    }
+    volumes[num_cols-1] = var;
+  }
+
+  // Write the wave form to LED display
+  for (int i = 0 ; i < num_cols; i++){
+    for (int j = 0 ; j < volumes[i]; j++){
+      hm.set_pixel(i, j, true);
+    }
+    for (int j = volumes[i] ; j < 8; j++){
+      hm.set_pixel(i, j, false);
+    }
+  }
 }

 int average(int* array, int length){
@@ -152,3 +152,4 @@
   unsigned long var = sum / length;
   return var;
 }
+


update motion

update motion

--- eMotion/flap/flap.ino
+++ eMotion/flap/flap.ino
@@ -93,7 +93,7 @@
         if(IR())
           delay(1000);
         else
-          delay(light() * rand() % 2000);
+          delay((light() * rand()) % 2000);
     }

     for(int i = start; i < start+n_serial; ++i)
@@ -102,7 +102,7 @@
         if(IR())
           delay(1000);
         else
-          delay(light() * rand() % 2000);
+          delay((light() * rand()) % 2000);
     }

 }


uno cleared of shared functions but the ISR is pukin on the playDit and playDah functions from common. I don't feel like dealing with this right now so uno is officially broken

--- firmware/firmware_uno/firmware_uno.ino
+++ firmware/firmware_uno/firmware_uno.ino
@@ -7,64 +7,7 @@
 int dahPin = 3; // Uno 3 has hardware interrupt
 int speakerPin = 5; // Digital pin 5 on uno is basic PWM

-  // CW characteristics
-int sideToneFreq = 622; // should be a pleasant tone in the range CW ops are used to
-int wpm = 20;         // operation word per minute
-  // I don't recommend changing anything below here.
-  // unless you are looking for some Farnsworth action. Then you could
-  // play with interLetterLength and interWordLength to achieve that effect.
-int ditLength = 1200 / wpm;   // this is the length of a dit in milliseconds at desired WPM
-int dahLength = 3 * ditLength;
-int interToneLength = ditLength;
-int interLetterLength = dahLength;
-int interWordLength = 7 * ditLength;
-boolean iambic = false; // Don't use this yet. There is a timing issue to figure out
-
-  // Play() setup
-  // map dit to TRUE and dah to FALSE for use in play
-boolean dit = true;
-boolean dah = false;
-boolean last;
-unsigned long now;
-unsigned long interToneLockTimer;
-
-void playDit() {
-  now = millis();
-  if (now > interToneLockTimer) {
-    tone(speakerPin, sideToneFreq, ditLength);
-  }
-  interToneLockTimer = millis() + interToneLength;
-  last = dit;
-}
-
-void playDah() {
-  now = millis();
-  if (now > interToneLockTimer) {
-    tone(speakerPin, sideToneFreq, dahLength);
-  }
-  interToneLockTimer = millis() + interToneLength;
-  last = dah;
-}
-
-void play(boolean sym) {
-  if (sym) {
-    playDit();
-  } else {
-    playDah();
-  }
-}
-
-void pause() {}
-
-void diDah() {
-  if (digitalRead(ditPin)==0 && digitalRead(dahPin)==0) {
-    play(!last);
-    pause();  // FIXME. How are you going to handle the timing
-              // between this pause and the lock in play()?
-  }
-}
-
-PCOCommon pcoCommon(ditPin, dahPin);
+PCOCommon pcoCommon(ditPin, dahPin, speakerPin);

 void setup()
 {
@@ -73,10 +16,10 @@
   pcoCommon.checkIfConfigure();

   // set up ditPin to read ditButton on regular Arduinos with 2 hardware interrups
-  attachInterrupt(0, playDit, LOW);
+  attachInterrupt(0, pcoCommon.playDit, LOW);

   // set up dahPin to read dahButton on regular Arduinos with 2 hardware interrups
-  attachInterrupt(1, playDah, LOW);
+  attachInterrupt(1, pcoCommon.playDah, LOW);
 }

 void loop()