code??
WaldoDTD
Posts: 142
Hello,
I have a program that sends control signals to a com port will this code work for the stamp so that all i have to do is turn it and the computer on and run the program on the computer that sends the signals to the stamp?
//Adam Brooks' Hack
import stamp.core.*;
public class Wintermute_Mrk_I {
static PWM servo1 = new PWM(CPU.pin12,173,2304);
static PWM servo2 = new PWM(CPU.pin13,173,2304);
public static void helpMessage() {
System.out.println("Valid commands are:");
System.out.println(" help - print this message");
System.out.println(" r1 - right servo 1");
System.out.println(" c1 - center servo 1");
System.out.println(" r2 - right servo 2");
System.out.println(" c2 - center servo 2");
}
public static void prompt() {
System.out.print("\n> ");
}
public static void main() {
while ( true ) {
char data;
StringBuffer cmd = new StringBuffer(20);
prompt();
while ( (data = Terminal.getChar()) != '\r' ) {
cmd.append(data);
}
System.out.print('\n');
if ( cmd.equals("help") ) {
helpMessage();
}
else if (cmd.equals("r1") ) {
servo1.update(64,2304);
}
else if (cmd.equals("c1") ) {
servo1.update(173,2304);
}
else if (cmd.equals("r2") ) {
servo2.update(64,2304);
}
else if (cmd.equals("c2") ) {
servo2.update(173,2304);
}
else {
System.out.print("\nUnknown command: ");
System.out.println(cmd.toString());
}
cmd.clear();
}
}
}
I have a program that sends control signals to a com port will this code work for the stamp so that all i have to do is turn it and the computer on and run the program on the computer that sends the signals to the stamp?
//Adam Brooks' Hack
import stamp.core.*;
public class Wintermute_Mrk_I {
static PWM servo1 = new PWM(CPU.pin12,173,2304);
static PWM servo2 = new PWM(CPU.pin13,173,2304);
public static void helpMessage() {
System.out.println("Valid commands are:");
System.out.println(" help - print this message");
System.out.println(" r1 - right servo 1");
System.out.println(" c1 - center servo 1");
System.out.println(" r2 - right servo 2");
System.out.println(" c2 - center servo 2");
}
public static void prompt() {
System.out.print("\n> ");
}
public static void main() {
while ( true ) {
char data;
StringBuffer cmd = new StringBuffer(20);
prompt();
while ( (data = Terminal.getChar()) != '\r' ) {
cmd.append(data);
}
System.out.print('\n');
if ( cmd.equals("help") ) {
helpMessage();
}
else if (cmd.equals("r1") ) {
servo1.update(64,2304);
}
else if (cmd.equals("c1") ) {
servo1.update(173,2304);
}
else if (cmd.equals("r2") ) {
servo2.update(64,2304);
}
else if (cmd.equals("c2") ) {
servo2.update(173,2304);
}
else {
System.out.print("\nUnknown command: ");
System.out.println(cmd.toString());
}
cmd.clear();
}
}
}
Comments
You must use·a receive and transmit Uart on two I/O pins.
The programming port puts out additional meta-databytes
and also cannot receive at will (that is, the PC may only
send a byte after it received a byte of value 0x12).
regards peter
the ability to change the PC program. That PC program
must act according to·the Javelin protocol.
The main() in the file you attached would be part of the mainloop of your PC program.
The other thing you must be aware of is that if you exit your PC program, the Javelin
will wait forever for a byte from the JIDE port. In my experience you can better disconnect
the cable from the JIDE port. Then there is a chance the Javelin merely times out on the JIDE port.
For that reason you really should have a blinking led on the javelin identifying the mainloop
is still executed. If that led stops blinking, the javelin waits for a byte from the JIDE port.
Then simply reconnect the cable and let the PC program send the 'no data' character.
So your PC program better has a button just to send that character.
regards peter
·
sendByte(), byteAvailable() and receiveByte() must be replaced when
using the protocol on a PC program by appropiate PC routines.
regards peter
then if the PC·has data, it must send 0x12 followed by 1·databyte,
otherwise it must send 0x13 (as defined by the protocol).
On the Javelin you use
if (Terminal.byteAvailable()) {
· char c = Terminal.getChar();
}
c can have any value from 0x00 to 0xFF
Best to have a unique value that is never data to synchronize,
eg. if 0xFE cannot be a databyte, start messages/commands with 0xFE.
If all values can be databytes, you could use bytestuffing. Then it would
make sense to use the Javelin protocol (which is bytestuffed)·to send
the PC data to the Javelin.
regards peter
·
· static void receiveTask(char ch) {
··· switch (state) {
····· case 0:· //no special chars received
·············· if (ch == 0x0F) { //first char after reset
················ state = 10;
················ break;
·············· }
·············· if (ch == 0x05) { //start of message
················ state = 20;
················ break;
·············· }
·············· if (ch == 0x11) { //javelin requests data
················ if (cmd) {
·················· SendByte((char)0x12);
·················· if (index == cmdlen) {
···················· SendByte((char)0x0D); //append CR,LF to end of command
···················· index++;
·················· }
·················· else if (index == cmdlen + 1) {
························· SendByte((char)0x0A);
························· cmd = false;
························· index = 0;
························· cmdlen = 0;
······················· }
······················· else {
························· SendByte(cmdbuf[noparse][[/noparse]index++]); //transmit next byte from cmdbuf
······················· }
················ }
················ else {
·················· SendByte((char)0x13); //reply with 'No data to send'
················ }
·············· }
·············· break;
····· case 10: //0x0F received
·············· state = 0; //ignore char following 0x0F
·············· break;
····· case 20: //0x05 received
·············· if (ch == 0x03) {·· //message header
················ state = 30;
················ break;
·············· }
·············· if (ch == 0x05) {·· //end of program
················ state = 40;
················ break;
·············· }
·············· state = 0;
·············· break;
····· case 30: //0x05 0x03 received
·············· if (ch == 0x7F) state = 31;· //bytestuffed char
·············· else {
················ if (ch == 0x7E) {
·················· state = 0; //end of message
················ }
················ else {
·················· DisplayChar(ch);
················ }
·············· }
·············· break;
····· case 31: //0x7F in messagedata
·············· ch = (char)(ch ^ 0x20); //ch = (<b>^0x20) ^ 0x20 = <b>
·············· DisplayChar(ch);
·············· state = 30;
·············· break;
····· case 40: //0x05 0x05 received
·············· state = 0; //ignore char following 0x05 0x05
·············· break;
····· default: state = 0;
·············· break;
··· }
· }
Important to note: this method assumes there is a buffer holding bytes that together
are regarded a single command. After the last byte has been transmitted, 0x0A,0x0D is appended
(CR,LF) because it is set up to transmit text only (You could have commands r1, c2 etc).
The javelin would recognize CR,LF as the end of a commandstring. No need for bytestuffing this
way. But 0x0A and 0x0D cannot be databytes.
regards peter
·
regards peter
program identifies the COM port
program sets the buffer sizes for I/O
program loops until it recieves byte 0x11 and then breaks
program stores each "control signals" (r,c,x in that form not in hex) in the buffer
program xmits one by one
program goes back to top loop
program breaks if a button is pressed in the GUI
program xmits 0x05
program closes the port
Post Edited (Hacker) : 8/5/2005 5:51:05 AM GMT
To send another byte, it must wait again for·0x11.
You really should try out my JideWin_Terminal program
First download JideTerm_protocol_test.java to the Javelin.
Leave the programming cable connected.
Close the Javelin IDE program.
Run "JideWin Terminal.exe"
Select com port Javelin is connected to.
Click Start
Enter any command in the command box.
While you do not·click Send, JideWin Terminal transmits 'no data' character to Javelin
when Javelin requests data. Once you click Send, all the characters from the command
box are send to the Javelin when the Javelin requests data.
One the Javelin has assembled a command, the javelin sends the command back to the
PC with a leading CMD:
So you can send commands like r1, c1, x, etc
You can also store those commands in a file and send that file to the javelin.
Each line in the file is a command and thus the file contents will show in the message
display.
The JideWin Terminal program implements the Javelin protocol exactly as discussed.
regards peter
<!-- Edit -->
simply wait for the next byte from the javelin.
The Format class can be found here:
http://groups.yahoo.com/group/JavelinCode/files/Javelin%20Stamp%20IDE/lib/stamp/util/text/
Place the class in folder lib/stamp/util/text
regards peter
Post Edited (Hacker) : 8/5/2005 9:38:18 PM GMT
The PC program never sends 0x05. It responds to a received 0x11 with either 0x13 or
with 0x12 <byte>.
Again, the protocol:
Debug messages sent from the Javelin conform to the following pattern:
0x05 0x03 <messagedata> 0x7E
<messagedata> is the sequence of bytes being sent by the CPU.message() native method. It is byte-stuffed. This means that if <messagedata> contains a byte <b> that has the value 0x7F or 0x7E then that byte is replaced with 0x7F <b>^0x20. i.e. 0x7F followed by the orginal byte xored with 0x20.
Terminal characters are sent to the Javelin using the following algorithm:
After the Javelin is reset it send 0x0F followed a pause followed by 0x50 (the version of the Javelin firmware).
Running the following simple program:
public class HelloWorld { public static void main() { System.out.println("Hello World"); } }
will generate the following on Sout:
0F 50 05 03 48 65 6C 6C 6F 20 57 6F 72 6C 64 7E 05 03 0D 0A 7E 05 05 7E
Note that the sequence 0x05 0x05 0x7E indicates that the Java program has ended.
The PC program never closes transmission or whatever. It merely responds to bytes received
from the Javelin.
regards peter
·
Post Edited (Hacker) : 8/5/2005 11:02:45 PM GMT
The byte received (= returned by Terminal.getChar()) will then be 0x72 (= 'r')
regards peter
static void main() {
char ch;
Format.printf("JideTerm protocol test program\n");
while (true) {
//perform terminal task
if (Terminal.byteAvailable()) {
ch = Terminal.getChar();
assembleCommand(ch);
if (cmd) {
Format.printf("CMD: %s\n",buf);
cmd = false;
index = 0;
}
}
if (buf.equals(0x72) ) {
servo1.update(64,2304);
}
if (buf.equals(0x63) ) {
servo1.update(173,2304);
}
}
}
Then cmd will be true. If your PC only sends single byte commands (eg. 'r' or 'c')
then you can simplify things.
·· static void main() {
··· char ch;
··· Format.printf("JideTerm protocol test program\n");
··· while (true) {
····· //perform terminal task
····· if (Terminal.byteAvailable()) {
······· ch = Terminal.getChar();
······· switch (ch) {
········· case 'r': servo1.update(64,2304);
··················· break;
········· case 'c': servo1.update(173,2304);
··················· break;
········· default:· //put error handling here
······· }
····· }
····· //perform other tasks
··· }
· }
regards peter
Then, again you wait for 0x11, then transmit 0x12 'c'.
In other words: you wait for 0x11, then transmit 0x12 and one databyte.
go here
·http://groups.yahoo.com/group/JavelinCode/files/JideTerm/
and download JideTerm_1_2.zip.
That is the commandline version of JideWin_terminal.
In the file main.c you find the receiveTask() statemachine again (as in the JideTerm_protocol.java file)
Actually, receiveTask() already shows it. Look at·when state == 0 (the case 0[noparse]:)[/noparse]
and when ch == 0x11. There you'll see the bytes stored in the buffer (eg. the command)
are transmitted one at a time, after 0x11 is received.
····· case 0:· //no special chars received
·············· if (ch == 0x0F) { //first char after reset
················ state = 10;
················ break;
·············· }
·············· if (ch == 0x05) { //start of message
················ state = 20;
················ break;
·············· }
······ //Here starts the part that transmits the command bytes
·············· if (ch == 0x11) { //javelin requests data
················ if (cmd) {
·················· SendByte((char)0x12);
·················· if (index == cmdlen) {
···················· SendByte((char)0x0D); //append CR,LF to end of command
···················· index++;
·················· }
·················· else if (index == cmdlen + 1) {
························· SendByte((char)0x0A);
························· cmd = false;
························· index = 0;
························· cmdlen = 0;
······················· }
······················· else {
························· SendByte(cmdbuf[noparse][[/noparse]index++]); //transmit next byte from cmdbuf
······················· }
················ }
················ else {
·················· SendByte((char)0x13); //reply with 'No data to send'
················ }
·············· }
·············· break;
regards peter
if (inputStream.available() > 0) {
cmd = true;
}
try {
while (inputStream.available() > 0) {
if (readBuffer == 0x11){//javilen requests stuff
if (cmd){
outputStream.write((notes)0x12.getBytes());
if (index == cmdlen){
outputStream.write((notes)0x0D);
index++;
}
else if (index == cmdlen + 1) {
outputStream.write((notes)0x0A);
cmd = false;
index = 0;
cmdlen = 0;
}
else {
outputStream.write(notes [noparse][[/noparse]index++]);//transmit next byte from notes
}
}
else {
outputStream.write((notes)0x13); //reply with 'No data to send'
}
}
break;
}
} catch (IOException e) {}
break;
}
·· Typically that's a linefeed (LF) and carriage return (CR).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
csavage@parallax.com
while (inputStream.available() > 0) {
if (readBuffer == 0x11){//javilen requests stuff
if (cmd){
outputStream.write((signals)0x12);
if (index == cmdlen){
outputStream.write((signals)0x0D);
index++;
}
I get the feeling you don't quite understand the javelin protocol.
When your javelin program calls Terminal.getChar() then the javelin transmits
0x11. The pc program must respond, and there are only 2 responses possible.
Either the pc program responds with 0x13 (no data to send) or it responds
with 0x12, followed by a single data byte. This data byte is the value returned
by the Terminal.getChar() method.
In my pc code, I attach a CR (0x0D) and LF (0x0A) to each message the pc
sends to the javelin. This is arbitrary, but allows the javelin program to recognize
the end of messages (my messages consists of printable characters only).
You could also use other techniques, like fixed size messages.
In the most simple form a message would consist of a single byte.
In case a message consists of multiple bytes, the pc must wait for 0x11, before
it sends ONLY 1 BYTE of the message, and that for each byte of the message.
regards peter
try {
while (inputStream.available() > 0) {
if (readBuffer == 0x11){//javilen requests stuff
while (st.hasMoreTokens()){
outputStream.write(0x12(st.nextToken()));
if (index == cmdlen){
outputStream.write(0x0D);
index++;
}
else if (index == cmdlen + 1) {
outputStream.write(0x0A);
cmd = false;
index = 0;
cmdlen = 0;
}