Code submission

Hi,
I’ve been looking at the remote control. The following code shows that readIR() returns a button press even after the button has been released (no problem, and it might be useful to know) and shows the time between the controller sending out codes if a button is held down.

[code] /*
IR Remote

Sparki has a sensor that lets it receives commands from
the included remote control.

The remote control outputs codes periodically while a button is
pushed. If readIR() is called after a code is received it
outputs that code once then outputs -1 if ut is called again
until the next code is recieved. This sketch helps determine
information about the remote and the readIR() function.
Open serial monitor when robot beeps.
Written by Philip Martel. This code is in the public domain.
*/
#include <Sparki.h>

SparkiClass robot;

void setup() {
int I;
robot.begin();
robot.beep();
delay(5000);
Serial.println(“press a few buttons. Release them before 0”);
for ( I = 5; I >= 0; I-- )
{
Serial.println(I);
delay(1000);
}
I = robot.readIR();
Serial.print(“code read after button is released “);
Serial.println(I);
Serial.print(”\nnow press and hold buttons to see “);
Serial.println(” time between codes”);
}
// /------^-----
// | |
// | 69 70 71 |
// | 68 64 67 |
// | 7 21 9 |
// | 22 25 13 |
// | 12 24 94 |
// | 8 28 90 |
// | 66 82 74 |
// ____________/

// note about 107500 microseconds between valid code values
// with the button held down.
void loop() {
static long LastTime = 0;
long Now;
int code = robot.readIR();
char S[20];
if(code != -1)
{
Now = micros();
sprintf(S,"%d %ld",code,Now - LastTime);
Serial.println(S);
LastTime = Now;
}

}
[/code]

This code is placed in the public domain.

Hi,

Here’s some more code based on the Remote example in the Sparki code. I felt that it was difficult to control Sparki and that the problem was largely that once you sent a turn command it kept turning until you deliberately sent some other command.

The readIR() function returns a value corresponding to the button pressed about once every 0.1 seconds. If readIR() is called when no button has been pressed or is called more often that once every 0.1 seconds, it returns -1. I’ve written a function newReadIR() that keeps track of the last button pressed and if much more than 0.12 seconds has elapsed since the a button code has been received, it returns the negative of the last code sent. This can be used to indicate that a button has been released.

I decided to use this to modify the Remote example code a bit. I set up a global variable, SavedCode, that stores the forward, backwards and stop motor commands. With this, you can start Sparki forward and then turn right. When you’re pointed in the direction you want, let go of the right turn button and Sparki will resume going forward automatically.
Enjoy!
–Phil Martel

/*
  Based on ArcBotics' IR Remote code
  
  Sparki has a sensor that lets it receives commands from
  the included remote control. Try moving it around!
 */ 
#include <Sparki.h>

SparkiClass robot;

int HeadAngle = 90;

int SavedCode = 21; // stop motion code 
char S[20];

void setup() {  
  robot.begin(); 
  robot.writeServo( HeadAngle );
}
// /------^-----\
// |            |
// | 69  70  71 |
// | 68  64  67 |
// |  7  21   9 |
// | 22  25  13 |
// | 12  24  94 |
// |  8  28  90 |
// | 66  82  74 |
// \____________/

// An extension of SparkiClass::readIR() It returns the code or -1 
// as readIR does, but if a key release is detected, it returns
// the negative of the code
int newReadIR(void)
{
  static long LastTime = 0;
  static int OldCode = -1;
  
  int long Now = micros();
  int code = robot.readIR();
  
  if ( code > 0 )
  {
    LastTime = Now;
    OldCode = code;
  }
  else if ((Now - LastTime) > 120000L )
  { // the pulses on my remote happen every 107500 microseconds
    // approximately
    LastTime = Now;
    if (OldCode > 0 )
    {
      code = -OldCode;
      OldCode = -1;
    }
  }
  return code;
}

void loop()
{  
  int code = newReadIR();
  
  if(code == -1) return;

  sprintf( S, "C:%d S:%d", code, SavedCode);
  Serial.println(S);
  // code to handle button being released
  switch(code)
  {
  case -9: // stop right turn
  case -7: // stop left turn
    code = SavedCode;
    break;
  case -13: // stop grip open
  case -22: // stop grip close
    robot.gripStop();
    break;
  default:
    break;
  }

  switch(code)
  {
  // Movement buttons
  case 64:
    robot.moveForward(); 
    SavedCode = code; // save forward motion
    break;
  case 25: 
    robot.moveBackward(); 
    SavedCode = code; // save backward motion
    break;
  case 9:  robot.moveRight(); break;
  case 7:  robot.moveLeft(); break;
  case 21: 
    robot.moveStop(); 
    SavedCode = code; // save motion stop
    break;
  
  // Gripper Buttons
  case 13:  robot.gripOpen(); break;
  case 22:  robot.gripClose(); break;
  
  // servo head
  case 68:
    HeadAngle = HeadAngle - 1;
    if ( HeadAngle <5 ) HeadAngle = 5;
    robot.writeServo(HeadAngle);
    delay(500);
    break;
  case 67:
    HeadAngle = HeadAngle + 1;
    if( HeadAngle > 175 ) HeadAngle = 175;
    robot.writeServo(HeadAngle);
    delay(500);
    break;
   
  case 24:
    robot.beep();
  break;
  case 12: //clear screen
    robot.clear();
    robot.display();
    break;
  case 94: // message 
    // the first character does not show 
    robot.drawstring(2, 2, " Hello, world."); 
    robot.display(); 
  default:
  break;
  }
}

thank you for this code, it makes the sparki much better. I added to it the bottom two rows of buttons for the RGB LED light as well as the red power button Case 69 to turn the LED off

A note: my head angle wasnt center so I defaulted it as 83, it looks like this may need to be adjusted on a case by case basis for the beta sparki

[code]/*
Based on ArcBotics’ IR Remote code

Sparki has a sensor that lets it receives commands from
the included remote control. Try moving it around!
*/
#include <Sparki.h>

SparkiClass robot;

int HeadAngle = 83;

int SavedCode = 21; // stop motion code
char S[20];

void setup() {
robot.begin();
robot.writeServo( HeadAngle );
}
// /------^-----
// | |
// | 69 70 71 |
// | 68 64 67 |
// | 7 21 9 |
// | 22 25 13 |
// | 12 24 94 |
// | 8 28 90 |
// | 66 82 74 |
// ____________/

// An extension of SparkiClass::readIR() It returns the code or -1
// as readIR does, but if a key release is detected, it returns
// the negative of the code
int newReadIR(void)
{
static long LastTime = 0;
static int OldCode = -1;

int long Now = micros();
int code = robot.readIR();

if ( code > 0 )
{
LastTime = Now;
OldCode = code;
}
else if ((Now - LastTime) > 120000L )
{ // the pulses on my remote happen every 107500 microseconds
// approximately
LastTime = Now;
if (OldCode > 0 )
{
code = -OldCode;
OldCode = -1;
}
}
return code;
}

void loop()
{
int code = newReadIR();

if(code == -1) return;

sprintf( S, “C:%d S:%d”, code, SavedCode);
Serial.println(S);
// code to handle button being released
switch(code)
{
case -9: // stop right turn
case -7: // stop left turn
code = SavedCode;
break;
case -13: // stop grip open
case -22: // stop grip close
robot.gripStop();
break;
default:
break;
}

switch(code)
{
// Movement buttons
case 64:
robot.moveForward();
SavedCode = code; // save forward motion
break;
case 25:
robot.moveBackward();
SavedCode = code; // save backward motion
break;
case 9: robot.moveRight(); break;
case 7: robot.moveLeft(); break;
case 21:
robot.moveStop();
SavedCode = code; // save motion stop
break;

// Gripper Buttons
case 13: robot.gripOpen(); break;
case 22: robot.gripClose(); break;

// servo head
case 68:
HeadAngle = HeadAngle - 1;
if ( HeadAngle <5 ) HeadAngle = 5;
robot.writeServo(HeadAngle);
delay(500);
break;
case 67:
HeadAngle = HeadAngle + 1;
if( HeadAngle > 175 ) HeadAngle = 175;
robot.writeServo(HeadAngle);
delay(500);
break;

case 24:
robot.beep();
break;
case 12: //clear screen
robot.clear();
robot.display();
break;
case 94: // message
// the first character does not show
robot.drawstring(2, 2, " Hello, world.");
robot.display();
default:
break;
// RGB lights on bottom 2 rows of IR Remote
case 8:
robot.RGB(255,0,0); // Make the LED maximum Red
delay(500); // wait 0.5 seconds (500 milliseconds)
break;
case 28:
robot.RGB(0,255,0); // Make the LED maximum Green
delay(500);
break;
case 90:
robot.RGB(0,0,255); // Make the LED maximum Blue
delay(500);
break;
case 66:
robot.RGB(255,0,255); // Make the LED maximum Violet
delay(500);
break;
case 82:
robot.RGB(0,255,255); // Make the LED maximum Aqua
delay(500);
break;
case 74:
robot.RGB(255,255,255); // Make the LED maximum White
delay(500);
break;
// Remote red button
case 69:
robot.RGB(0,0,0); // Make the LED turn off
delay(500);
break;
case 71:
// Remote Menu button make yellow
robot.RGB(255,255,0); // Make the LED maximum yellow
delay(500);
break;
}
}[/code]

Thanks for sharing

Led Lighting Effects