Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moved command parser to library, added motor test (which is working w…
…ith a motor!)
- Loading branch information
Showing
5 changed files
with
338 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
*~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
Copyright (c) 2011 Guy Carpenter | ||
*/ | ||
|
||
#include <Arduino.h> | ||
#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; i<COMMAND_TUPLE_LEN; i++) { | ||
if (parseInteger(line, len, tuple+i+1)) { | ||
result = true; | ||
tuple[0] = i+1; | ||
if (*len>0 && **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; | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
|
||
#ifndef Command_h | ||
#define Command_h | ||
|
||
#include <Arduino.h> | ||
#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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<count;i++) { | ||
state6(); | ||
state5(); | ||
state4(); | ||
state3(); | ||
state2(); | ||
state1(); | ||
} | ||
|
||
for (int i=0;i<count;i++) { | ||
state1(); | ||
state2(); | ||
state3(); | ||
state4(); | ||
state5(); | ||
state6(); | ||
} | ||
|
||
for (int i=0;i<count/2;i++) { | ||
state6(); | ||
state5(); | ||
state4(); | ||
state3(); | ||
state2(); | ||
state1(); | ||
} | ||
|
||
} | ||
|
||
void loop() | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
PROTOCOL: | ||
|
||
Actions: | ||
|
||
DIAL <n> <value> | ||
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 <n> <value> | ||
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) | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|