help with uart
I am having trouble understanding how to use the uart.· Specifically, how to read and use the data that is in the buffer.·My problem is I am recieving packets of information via the uart that vary in length and content. ·The packets have a structure but the number of data elements in the packet can vary.
byte 1 = command
byte 2 = number of data elements
byte 3 = data1
byte 4 = data2
.
.
.
.
byte x = checksum low byte
byte y = checksum high byte
The·BS2p code I have looks like this:
·main:
·· SERIN 8, 110, [noparse][[/noparse]STR serbuf\serbuf(1)+4]
·· FOR index = 0 TO 9
·· NEXT
·· LOOKDOWN serbuf(0), [noparse][[/noparse]64,128,129,130], cmd
·· ON cmd GOSUB normal, cmd1, cmd2, cmd3,·cmd4
·· IF cmd > 3 THEN DEBUG CLS, "Command not in list"
·· GOTO main
Since the packets will allways have a minimum length of 4 bytes (cmd,0 data,cclow,cchigh), i can tell the serial·command when to stop reading bytes.· Then by reading the individual positions in the array i can have the program act accordingly.· I am lost on how to do this (or even if i need to) with the javelin.
any ideas?
byte 1 = command
byte 2 = number of data elements
byte 3 = data1
byte 4 = data2
.
.
.
.
byte x = checksum low byte
byte y = checksum high byte
The·BS2p code I have looks like this:
·main:
·· SERIN 8, 110, [noparse][[/noparse]STR serbuf\serbuf(1)+4]
·· FOR index = 0 TO 9
·· NEXT
·· LOOKDOWN serbuf(0), [noparse][[/noparse]64,128,129,130], cmd
·· ON cmd GOSUB normal, cmd1, cmd2, cmd3,·cmd4
·· IF cmd > 3 THEN DEBUG CLS, "Command not in list"
·· GOTO main
Since the packets will allways have a minimum length of 4 bytes (cmd,0 data,cclow,cchigh), i can tell the serial·command when to stop reading bytes.· Then by reading the individual positions in the array i can have the program act accordingly.· I am lost on how to do this (or even if i need to) with the javelin.
any ideas?
Comments
static Uart rx = new Uart(...);
static char[noparse]/noparse msg = new char[noparse][[/noparse]256]; //size equals max. message size
static int index = 0;
static boolean assemble() { //return true for complete message, else return false
· if (!rx.byteAvailable()) return false;
· msg[noparse][[/noparse]index++] = (char)rx.receiveByte();
· if (index >= 4) { //check for number of bytes
··· if ((msg[noparse][[/noparse]1]+4) == index) {
····· index = 0;
····· return true;
··· }
··}
· return false;
}
static void main() {
· while (true) {
··· while (!assemble()) ; //wait for complete message
··· //process message
· }
}
regards peter
Following is the relevant code from the current Insteon class (full code is in Insteon.java·at http://www.cls01.com/insteon/). Note that this is beta and there may be a better/more efficient way to do this (feedback appreciated!).
static final int PLCpinTX = CPU.pin9;
static final int PLCpinRX = CPU.pin10;
static Uart tx = new Uart(Uart.dirTransmit, PLCpinTX, Uart.dontInvert, Uart.speed4800, Uart.stop1);
static Uart rx = new Uart(Uart.dirReceive, PLCpinRX, Uart.dontInvert, Uart.speed4800, Uart.stop1);
static Timer t1 = new Timer();
· /**
·· * Read a Command from the PLC
·· *
·· * @param buffer Character buffer to store command data read
·· * @return
·· *··· >0 = Command read from the PLC,
·· *··· -1 = No data available from PLC,
·· *··· -2 = First byte not STX,
·· *··· -3 = Error reading 2nd byte from PLC,
·· *··· -4 = Unknown command read,
·· *··· -5 = Error reading command data from PLC
·· */
· private int readCommand(char[noparse]/noparse buffer) {
··· int nextByte;
··· int thisCommand;
··· int dataLength;
··· int rtnCode;
··· boolean receivedSTX = false;
··· nextByte = getByte(200);
··· if (nextByte < 0) return -1;
··· if (nextByte != IBIOS_STX) return -2; // not STX
··· nextByte = getByte(200);
··· if (nextByte < 0) return -3;
··· thisCommand = nextByte;
··· switch (thisCommand) {
····· case IBIOS_DOWNLOAD:
······· dataLength = 0;
······· break;
····· case IBIOS_MASK:
······· dataLength = 0;
······· break;
····· case IBIOS_X10_BYTE_RECEIVED:
······· dataLength = 2;
······· break;
····· case IBIOS_EVENT_REPORT:
······· dataLength = 1;
······· break;
····· case IBIOS_GET_VERSION:
······· dataLength = 7;
······· break;
····· default:························ // unknown command
······· return -4;
··· }
··· rtnCode = readData(dataLength,buffer);
··· if (rtnCode < 0) return -5;
··· return thisCommand;
· }
· /**
·· * Read Data from the PLC
·· * @param bytesToRead Number of bytes to read
·· * @param buffer Character buffer to store data read
·· * @return
·· *··· >=0 = Last byte read,
·· *··· -1 = Error while reading from PLC
·· */
· private int readData(int bytesToRead, char[noparse]/noparse buffer) {
··· int nextByte;
··· int i = 0;
··· nextByte = 0;
··· while (bytesToRead>0) {
····· nextByte = getByte(2000);
····· if (nextByte < 0) return -1;
····· i++;
····· buffer[noparse][[/noparse]i] = (char)nextByte;
····· buffer[noparse][[/noparse]0] = (char)i;
····· --bytesToRead;
··· }
··· return nextByte;
· }
· /**
·· * Get a Byte from the PLC
·· * @param waitTime Number of ms to wait for data
·· * @param buffer Character buffer to store data read
·· * @return
·· *··· >=0 = Last byte read,
·· *··· -1 = No data available before timeout
·· */
· private int getByte(int waitTime) {
··· int byteRead;
··· t1.mark();
··· while(!t1.timeout(waitTime) && !rx.byteAvailable());
··· if (!rx.byteAvailable()) return -1;
··· byteRead = rx.receiveByte() & 0xff;
··· //DEBUG Format.printf("{%02x}",byteRead);
··· return byteRead;
· }
Thanks for the help....I am so new to this stuff that it takes me a while to see what is going on with the code. It looks like there are parts that can help me , in particular , the timer. I had not thought about what would happen if there was no response to a request.
Please forgive me if this question is really dumb, I know a good amount about programming but absolutely nothing about how data is transmitted through parallel and rs232 cables. Any help on this matter would be greatly appreciated.
Thanks,
Rob
The parallel port outputs its data on 8 datapins, and then
a control pin is strobed. You must either send your data
to·a serial port (COM1, COM2), or use an external parallel-to-serial converter device.
Then you can use a uart to receive data.
regards peter
Post Edited (Peter Verkaik) : 5/16/2006 1:08:24 PM GMT