Working on a serial data logger and am stuck. Need some help and suggestions....
Don M
Posts: 1,652
I am trying to data log serial data (9600 baud, 9 bit). I am using a modified serial object modified for 9 bit. It has methods similar in function to FDS. I am running 2 instances of the serial object- 1 for the Master and 1 for Slave. The buffers bufm[36], bufs[36] are defined as word buffers in order to store the 9th bit.
The Master starts its communication with the 9th bit set so for instance a command (with checksum) of 0B would look like this: 10B 00B. The 1 indicates the start of the Master command. The Master ACK does not have the 9th bit set so it will look like this: 000.
The Slave response begins without the 9th bit set except for an ACK. The slave ACK looks like this: 100. The slave response ends with the last byte having the 9th bit set.
So what I tried to do was use these "signatures", if you will, of determining whether or not the 9th bit is set to figure out the begining or end of data strings.
Here is my code:
It works fine as long as there is only 1 Slave device on the bus. If I tell the Master to look for an additional slave device (with a different address) that doesn't happen to be attached to the bus I start to have problems.
Here's a screen shot of just 1 Slave device connected and logging. M1: indicates the start of Master command. S: is the Slave response. M2: is the Master ACK response. Remember anything beginng with a "1" indicates the 9th bit set.
Now here's a screen shot showing another device with the address of 30 that is being looked for by the Master but is not connected so it doesn't respond and ACK the Master.
You can see in the 6th line that begins: M1: 130 030 130 030 .... 10A 00A S: 000 000 and so on. The 130 030 is the Master looking for device with the address of 30 that is not connected thus no response. What I want my program to do is if it doesn't get an ACK from a device then the display should look like this:
The program should just send a carriage return if it doesn't receive anthing from the device.
I know I'm not the smartest programmer and I have spent several days trying to add term.tx(13) in certain locations among a myriad of other things to no avail. I tried adding an "else" statement with a term.tx(13) to the "if (d<>1) loop and that didn't work.
I need another set of eyes to look at this for some guidance. Somehow it has to be determined when the Master has sent a command that is not responded to in a certain amount of time. i thought that was what rx_time(x) was supposed to do. When it timed out it sends a -1 to indicate buffer empty.
Maybe this whole structure is wrong.... Any ideas or suggestions?
Thanks.
Don
The Master starts its communication with the 9th bit set so for instance a command (with checksum) of 0B would look like this: 10B 00B. The 1 indicates the start of the Master command. The Master ACK does not have the 9th bit set so it will look like this: 000.
The Slave response begins without the 9th bit set except for an ACK. The slave ACK looks like this: 100. The slave response ends with the last byte having the 9th bit set.
So what I tried to do was use these "signatures", if you will, of determining whether or not the 9th bit is set to figure out the begining or end of data strings.
Here is my code:
pub main | d, c, i, j, num_bytes term.start(31, 30, %0000, 115_200) ' start terminal (use PST) pause(500) master.start(MSTR, -1,%10) ' start receiving master comms slave.start(SLAV, -1,%00) ' start receiving slave comms master.rx_flush slave.rx_flush repeat d := master.rx ' assign d to data coming in from Master c := slave.rx ' assign c to data coming in from Slave if(d <> -1) ' look for any data coming in from Master bufm[0] := d ' store d in Master buffer i := 1 ' initialize buffer i index counter repeat ' repeat loop to store data into Master buffer d := master.rx_time(10) ' receive Master data into d if(d == -1) or (i => 36) ' until no data received or Master buffer is full master.rx_flush ' flush Master receive buffer quit ' quit receiving data into Master buffer bufm[i] := d ' put d data into Master buffer position indexed by i i++ ' increment i buffer index counter num_bytes := i ' assign number of i bytes to num_bytes term.str(string("M1: ")) ' begin display for Master bytes repeat i from 0 to num_bytes - 1 ' loop through Master buffer to display term.hex(bufm[i], 3) ' show 3 bytes of word to see if 9th bit set term.tx(32) ' add a space in between data for clarity if (c <> -1) ' look for any data coming in from Slave bufs[0] := c ' store c in Slave buffer j := 1 ' initialize buffer j index counter repeat ' repeat loop to store data into Slave buffer c := slave.rx_time(4) ' receive Slave data into c if(c == -1) or (j => 36) ' until no data received or Slave buffer is full slave.rx_flush ' flush Slave receive buffer quit ' quit receiving data into Slave buffer bufs[j] := c ' put c data into Slave buffer position indexed by j j++ ' increment j buffer index counter num_bytes := j ' assign number of j bytes to num_bytes term.str(string("S: ")) ' begin display for Slave bytes repeat j from 0 to num_bytes - 1 ' loop through Slave buffer to display term.hex(bufs[j], 3) ' show 3 bytes of word to see if 9th bit set term.tx(32) ' add a space in between data for clarity if (c & $1_00) == $1_00 ' check if c contains 9th bit set to indicate end of data if bufs[0] == $1_00 ' check to see if only a Slave ACK term.tx(13) ' if so then just do CR else ' otherwise wait for Master ACK and display it term.str(string("M2: ")) d := master.rx term.hex(d, 3) term.tx(13)
It works fine as long as there is only 1 Slave device on the bus. If I tell the Master to look for an additional slave device (with a different address) that doesn't happen to be attached to the bus I start to have problems.
Here's a screen shot of just 1 Slave device connected and logging. M1: indicates the start of Master command. S: is the Slave response. M2: is the Master ACK response. Remember anything beginng with a "1" indicates the 9th bit set.
Now here's a screen shot showing another device with the address of 30 that is being looked for by the Master but is not connected so it doesn't respond and ACK the Master.
You can see in the 6th line that begins: M1: 130 030 130 030 .... 10A 00A S: 000 000 and so on. The 130 030 is the Master looking for device with the address of 30 that is not connected thus no response. What I want my program to do is if it doesn't get an ACK from a device then the display should look like this:
The program should just send a carriage return if it doesn't receive anthing from the device.
I know I'm not the smartest programmer and I have spent several days trying to add term.tx(13) in certain locations among a myriad of other things to no avail. I tried adding an "else" statement with a term.tx(13) to the "if (d<>1) loop and that didn't work.
I need another set of eyes to look at this for some guidance. Somehow it has to be determined when the Master has sent a command that is not responded to in a certain amount of time. i thought that was what rx_time(x) was supposed to do. When it timed out it sends a -1 to indicate buffer empty.
Maybe this whole structure is wrong.... Any ideas or suggestions?
Thanks.
Don
Comments
In the beginning of the repeat loop where c := slave.rx, the .rx method will just sit and wait until there is any data which causes a problem when there isn't any Slave response.
Here is my updated code that works quite a bit better but may still need further testing:
Any other suggestions welcome.
Thanks.
Don