diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..b25c15b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*~ diff --git a/Command.cpp b/Command.cpp new file mode 100755 index 0000000..69e1806 --- /dev/null +++ b/Command.cpp @@ -0,0 +1,105 @@ +/* + Copyright (c) 2011 Guy Carpenter +*/ + +#include +#include "Command.h" + +#define CMDBUF_LEN 40 + + +void Command::skipWhitespace(char **line, int *len) +{ + while (*len > 0 && **line == ' ') { + (*len)--; + (*line)++; + } +} + + +boolean Command::parseCommand(char **line, int *len, char *cmd) +{ + boolean result = false; + skipWhitespace(line, len); + if (*len > 0) { + *cmd = **line; + (*len)--; + (*line)++; + result = true; + } + return result; +} + + +boolean Command::parseInteger(char **line, int *len, value_t *value) +{ + boolean result = false; + *value = 0; + while (*len>0 && **line>='0' && **line<='9') { + *value = *value * 10 + (**line - '0'); + (*len)--; + (*line)++; + result = true; + } + return result; +} + +boolean Command::parseTuple(char **line, int *len, value_t *tuple) +{ + boolean result = false; + skipWhitespace(line, len); + for (int i=0; i0 && **line == ',') { + // found comma, so more integers expected + (*len)--; + (*line)++; + result = false; // need another int to succeed + } else { + break; + } + } else { + break; + } + } + return result; +} + +boolean Command::parseLine(char *line, int len) +{ + boolean result = false; + if (parseCommand(&line, &len, &command) && + parseTuple(&line, &len, address) && + parseTuple(&line, &len, value)) { + result = true; + } else { + Serial.println("$Error Invalid command syntax"); + } + return result; +} + + +boolean Command::parseInput() +{ + boolean result = false; + static char line[CMDBUF_LEN]; // NOT zero terminated + static int len = 0; + + if (Serial.available()) { + char c = Serial.read(); + if (c==10 || c==13) { + result = parseLine(line, len); + len = 0; + } else if (len < CMDBUF_LEN) { + line[len++] = c; + } + return result; + } +} + + + + + diff --git a/Command.h b/Command.h new file mode 100755 index 0000000..f56ed26 --- /dev/null +++ b/Command.h @@ -0,0 +1,27 @@ + +#ifndef Command_h +#define Command_h + +#include +#define COMMAND_TUPLE_LEN 3 +typedef unsigned int value_t; + +class Command +{ + public: + char command; + value_t address[COMMAND_TUPLE_LEN+1]; + value_t value[COMMAND_TUPLE_LEN+1]; + + private: + void skipWhitespace(char**, int*); + boolean parseCommand(char **line, int *len, char *cmd); + boolean parseInteger(char **line, int *len, value_t *value); + boolean parseTuple(char **line, int *len, value_t *tuple); + boolean parseLine(char *line, int len); + public: + boolean parseInput(); +}; + +#endif + diff --git a/motortest/motortest.ino b/motortest/motortest.ino new file mode 100755 index 0000000..2733e42 --- /dev/null +++ b/motortest/motortest.ino @@ -0,0 +1,113 @@ +int motorPin1 = 8; // orange +int motorPin2 = 9; // brown +int motorPin3 = 10; // blue +int motorPin4 = 11; // green +int delayTime = 5; +int count = 157; + +// 6 steps per motor rotation +// 180:1 gear +// 180 * 6 steps per rotation +// 2 degrees per 6-states +// stops liit to 315 degrees +// 315 = 157.5 steps +// maximum speed seems to be about 800 microseconds delay + +void setup() { + pinMode(motorPin1, OUTPUT); + pinMode(motorPin2, OUTPUT); + pinMode(motorPin3, OUTPUT); + pinMode(motorPin4, OUTPUT); + center(); +} + +void pause() +{ + delayMicroseconds(800); +} + +void state1() { + digitalWrite(motorPin1, HIGH); + digitalWrite(motorPin2, LOW); + digitalWrite(motorPin3, LOW); + digitalWrite(motorPin4, HIGH); + pause(); +} + +void state2() { + digitalWrite(motorPin1, HIGH); + digitalWrite(motorPin2, LOW); + digitalWrite(motorPin3, LOW); + digitalWrite(motorPin4, LOW); + pause(); +} + +void state3() { + digitalWrite(motorPin1, HIGH); + digitalWrite(motorPin2, HIGH); + digitalWrite(motorPin3, HIGH); + digitalWrite(motorPin4, LOW); + pause(); +} + +void state4() +{ + digitalWrite(motorPin1, LOW); + digitalWrite(motorPin2, HIGH); + digitalWrite(motorPin3, HIGH); + digitalWrite(motorPin4, LOW); + pause(); +} + +void state5() { + digitalWrite(motorPin1, LOW); + digitalWrite(motorPin2, HIGH); + digitalWrite(motorPin3, HIGH); + digitalWrite(motorPin4, HIGH); + pause(); +} + +void state6() +{ + digitalWrite(motorPin1, LOW); + digitalWrite(motorPin2, LOW); + digitalWrite(motorPin3, LOW); + digitalWrite(motorPin4, HIGH); + pause(); +} + + +void center() +{ + for (int i=0;i + set gauge to value + I think 100 is not enough steps, + so maybe express as float or 1000ths or 0..255 + or query the device to get the fsd range + +LED + set led on or off. If we have multiple leds + per device we could address them as 1,1 + RGB values? LED 1,1 100,255,128 + +So what about generalizing dial and led to a single command: + +SET a v +where n is an address (which could be a comma separated list) +and v is a value (which could be a comma separated list) + +SET 0 0 +GET 0 echos back "a v" (or maybe "a v t", see below regarding time stamps) + +Later if we support input we can get unsolicited input: "a v" +in the same format, so a push button event might be: + +0,1 1 +0,1 0 + +Maybe we want a time stamp to help determine duration of events? + +0,1 1 1234 +0,1 1 1238 + +====================================================================== +command parser + +What we want to get: + First letter of command + Address tuple + Value tuple + +Each tuple should be +count,value0,value1... + +parser should call + command_handler(command, address, value) +where command is a byte representing the command. +(the first character of the command?), address is a vector of bytes, +and value is a vector of bytes. + +Hmmm - that limits me to 256 step resolution, which seems poor. +What about making the values 16-bit signed integers instead? +That seems better. + +S 0,0 1000 +S 0,0 0 +G 0,0 + +Maximum tuple length is 3 (for rgb) so we need 2 x 4 int16 arrays or 16 bytes. +Seems fine. + +So in loop we call the parser +loop: + if there is a character ready, parse_character +end + +parse_command checks for serial input. +It could state-machine or parse on CRLF. The latter +would allow backspaces! + +parse_character(c) + if input + if input is crlf terminate input string and parse it + else + if buffer is not full add to end of buffer + +parse_line(buffer, length) + c = parse_command + a = parse_tuple + v = parse_tuple + +command_handler(c,a,v) + + + + + + + +