Archive for the ‘C/C++’ Category

Drawbot Calibration, part 2

Wednesday, February 22nd, 2012

The test pattern is based on one I saw being done by the incredible H5GBSD.

Drawing Lines, Arcs, and Halftones with a Wall Hanging Arduino Drawbot

Monday, February 13th, 2012

Download Drawbot Arduino code here

Among the various features are…

Verbose output: Debugging line and arc drawing took a lot of work and I see no reason to remove all the helpful debugging messages.  Maybe it will give you insights to my madness.  uncomment #define VERBOSE to see the storm of messages in the serial interface.

Serial command interface: Type commands to the drawbot and it will execute them.  Draw all the arcs & lines you want.  Write a javascript app to send whole SVG files to your drawbot.  Don’t worry about mistakes because I’ve added

Sanity checking: Try to send the drawbot out of the work envelope and it will refuse with a cryptic error message.

Why do I hear so many complaints about the lack of memory on Arduinos?  This was only 20k (compiled) and should run on every flavor of Arduino.

Edit: I had all the sourcecode in the post and it drove me nuts trying to keep it in sync with the working copy. Just click the link and get the latest there.

Controlling your Arduino through the Serial Monitor

Tuesday, October 18th, 2011

When I’m developing Arduino code, I often have variables that need to be tweaked during testing & calibration.
Rather than recompile and upload the code (a time consumin process) I wrote a few lines to let me open the Serial Monitor and send commands directly.

I hope you find this useful – I use it in all my robots!

//------------------------------------------------------------------------------
// Serial Monitor control example
// dan@marginallyclever.com 2011-10-17
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// constants
//------------------------------------------------------------------------------
#define DELAY   (5)
#define BAUD    (57600)
#define MAX_BUF (64)

//------------------------------------------------------------------------------
// global variables
//------------------------------------------------------------------------------
char buffer[MAX_BUF];
int sofar;

char test_on=0;  // only used in processCommand as an example.
float pos_x;
float pos_y;
float pos_z;

//------------------------------------------------------------------------------
// methods
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void jog(float x, float y, float z) {
  // do some tests here to validate x, y, and z.
  pos_x=x;
  pos_y=y;
  pos_z=z;
}

//------------------------------------------------------------------------------
void processCommand() {
  if(!strncmp(buffer,"help",4)) {
    Serial.println("commands: where; test (1/0); jog [x(float)] [y(float)] [z(float)];");
  } else if(!strncmp(buffer,"where",5)) {
    // no parameters
    Serial.print(pos_x);
    Serial.print(", ");
    Serial.print(pos_y);
    Serial.print(", ");
    Serial.println(pos_z);
  } else if(!strncmp(buffer,"test",4)) {
    // one whole number parameter
    char *state=strchr(buffer,' ')+1;
    Serial.println(state);
    if(state[0]=='0') {
      Serial.println("End test");
      test_on=0;
    } else {
      Serial.println("Start test");
      test_on=1;
    }
  } else if(!strncmp(buffer,"jog",3)) {
    // several optional float parameters.
    // then calls a method to do something with those parameters.
    float xx=pos_x;
    float yy=pos_y;
    float zz=pos_z;

    char *ptr=buffer;
    while(ptr && ptr<buffer+sofar) {
      ptr=strchr(ptr,' ')+1;
      switch(*ptr) {
      case 'x': case 'X': xx=atof(ptr+1);  Serial.print('x'); Serial.println(xx); break;
      case 'y': case 'Y': yy=atof(ptr+1);  Serial.print('y'); Serial.println(yy); break;
      case 'z': case 'Z': zz=atof(ptr+1);  Serial.print('z'); Serial.println(zz); break;
      default: ptr=0; break;
      }
    }

    jog(xx,yy,zz);
  }
}

//------------------------------------------------------------------------------
void setup() {
  Serial.begin(BAUD);
  Serial.println("Init...");
  Serial.println("Stretching...");

  sofar=0;
  Serial.println("** AWAKE **");
}

//------------------------------------------------------------------------------
void loop() {
  // listen for serial commands
  while(Serial.available() > 0) {
    buffer[sofar++]=Serial.read();
    if(buffer[sofar-1]==';') break;  // in case there are multiple instructions
  }

  // if we hit a semi-colon, assume end of instruction.
  if(sofar>0 && buffer[sofar-1]==';') {
    // what if message fails/garbled?

    // echo confirmation
    buffer[sofar]=0;
    Serial.println(buffer);

    // do something with the command
    processCommand();

    // reset the buffer
    sofar=0;

    // echo completion
    Serial.println("Done.");
  }
}

Surrounded – my first cross platform OpenGL game

Sunday, September 18th, 2011

Recently Joel was going through the old Flipcode site and noticed a broken link to one of my old projects, Surrounded. It’s was my first attempt to write code that was easily cross-platform (windows, linux, and mac OSX). It’s a bit like smash TV, except that I never got around to making the wide variety of enemies that I should have. An exercise for the reader!

Surrounded 1.0

Here in this zip I’ve included all the source code, project files, and a pre-compiled windows executable. It is provided without warranty etc.  If you build the appropriate project files for cocoa it should compile in OSX, and same goes for GCC/linux

Using a Rotary Encoder with Arduino

Sunday, March 27th, 2011

Arduino / rotary encoder wiring example

A rotary encoder is essential in most analog to digital measurements. Everything from volume control to robot movement can be tracked with a good rotatry encoder. Conveniently, everything you need to know is in Wikipedia. This code is a variation on Metsfan’s contribution to the Sparkfun forums. This version avoids unnecessary if statements. SO NERDY.

#define PIN_HIGHBIT (7)
#define PIN_LOWBIT  (5)
#define PIN_PWR     (3)
#define BAUDRATE    (9600)
#define DEBUG         (1)

// globals
int state, prevState = 0, count = 0;
/* old state, new state, change (+ means clockwise)
 * 0 2 +
 * 1 0 +
 * 2 3 +
 * 3 1 +
 * 0 1 -
 * 1 3 -
 * 2 0 -
 * 3 2 -
 */
int encoderStates[4][4] = {
 {  0, -1,  1,  0 },
 {  1,  0,  0, -1 },
 { -1,  0,  0,  1 },
 {  0,  1, -1,  0 },
};

void setup() {
  pinMode(PIN_HIGHBIT, INPUT);
  pinMode(PIN_LOWBIT, INPUT);
  pinMode(PIN_PWR, OUTPUT);
  digitalWrite(PIN_PWR, LOW);
  digitalWrite(PIN_LOWBIT, HIGH);
  digitalWrite(PIN_HIGHBIT, HIGH);
  Serial.begin(BAUDRATE);
}

void loop() {
  state = (digitalRead(PIN_HIGHBIT) << 1) | digitalRead(PIN_LOWBIT);
  count += encoderStates[prevState][state];

#ifdef DEBUG
  if (state != prevState) {
    Serial.print(state, DEC);
    Serial.print(' ');
    Serial.print(prevState, DEC);
    Serial.print(' ');
    Serial.println(count, DEC);
  }
#endif

  prevState = state;
}