First time using UART - Using PST and FullDuplexSerial - Not working?
in Propeller 1
Hey guys,
This is my first time using UART and I can't seem to get it to work. I am interfacing the propeller with a MH-Z14 CO2 sensor:
http://www.thaieasyelec.com/downloads/ESEN185/MH-Z14_CO2.pdf
I am using the "Parallax Serial Terminal" library to display information to the terminal, and I am using the "FullDuplexSerial" library for the UART communication with the sensor. This is something that I am not sure about.
I send commands to the sensor but I never receive anything back from the Rx read... it locks up and waits forever for data to come but it never comes.
I tried swapping the Rx and Tx lines around, and like this I constantly receive 0's.
I have the Rx of the propeller connected to the Tx of the sensor, and the Tx of the propeller connected to the Rx of the sensor.
I made a quick sample SPIN program just to try and test it, but it does not work.
Would someone mind taking a peek and letting me know what I am doing wrong? Thanks and any help is greatly appreciated.
Here is my SPIN program:
This is my first time using UART and I can't seem to get it to work. I am interfacing the propeller with a MH-Z14 CO2 sensor:
http://www.thaieasyelec.com/downloads/ESEN185/MH-Z14_CO2.pdf
I am using the "Parallax Serial Terminal" library to display information to the terminal, and I am using the "FullDuplexSerial" library for the UART communication with the sensor. This is something that I am not sure about.
I send commands to the sensor but I never receive anything back from the Rx read... it locks up and waits forever for data to come but it never comes.
I tried swapping the Rx and Tx lines around, and like this I constantly receive 0's.
I have the Rx of the propeller connected to the Tx of the sensor, and the Tx of the propeller connected to the Rx of the sensor.
I made a quick sample SPIN program just to try and test it, but it does not work.
Would someone mind taking a peek and letting me know what I am doing wrong? Thanks and any help is greatly appreciated.
Here is my SPIN program:
CON
_clkmode = xtal1 + pll16x 'Standard clock mode * crystal frequency = 80 MHz
_xinfreq = 5_000_000
OBJ
PST : "Parallax Serial Terminal" ''Used ONLY For DEBUGGING
UART : "FullDuplexSerial"
VAR
byte buffer
PUB Main
PST.Start(115200) 'Used ONLY For DEBUGGING
waitcnt(clkfreq / 2 + cnt) 'Allow device time to power up fully
PST.Clear
PST.Str(string("Parallax Serial Terminal Initialized",13))
UART.start(16, 17, %0000, 9_600)
waitcnt(clkfreq + cnt) 'Allow device time to power up fully
PST.Str(string("UART Initialized",13))
UART.RxFlush
UART.Hex($FF,2)
UART.Hex($01,2)
UART.Hex($86,2)
UART.Hex($00,2)
UART.Hex($00,2)
UART.Hex($00,2)
UART.Hex($00,2)
UART.Hex($00,2)
UART.Hex($79,2)
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))
buffer := UART.Rx
PST.Hex(buffer,2)
PST.Str(string(13))

Comments
You're sending 18 bytes to a device expecting 9. Just send the binary values without converting them to strings.
A second look also indicates you must calculate a checksum byte at the end.
Here's the [tested] translation of the checksum calculation; I did my best to make it very verbose so you can compare the Spin to C.
char getCheckSum(char *packet) { char i, checksum; for( i = 1; i < 8; i++) { checksum += packet[i]; } checksum = 0xff – checksum; checksum += 1; return checksum; }pub get_checksum(p_packet) | idx, checksum checksum := 0 repeat idx from 1 to 7 checksum += byte[p_packet][idx] checksum := $FF - checksum.byte[0] checksum += 1 return checksumThe reason for using checksum.byte[0] after the loop is to isolate just the lower eight bits. In the C implementation, checksum is defined as a char (8 bits). In Spin, all local variables are longs (32 bits).There are no pointer variables in Spin, so I preface a variable that is to hold a pointer with "p_".
As you gain more experiece you can start to cut the fat out of programs. Here's a version of get_checksum that doesn't require local variables (other than built in result).
EDITED:
pub get_checksum(p_packet) : checksum repeat 7 checksum += byte[++p_packet] checksum := $FF - checksum.byte[0] checksum += 1I tested it (the original version) on the same data sets from the sensor docs. It works fine -- because I got lucky (see my post below).I changed the UART.Hex($FF,2) over to UART.Tx($FF) and now everything works. Thanks for the checksum code as well!
pub get_checksum(p_packet) : checksum repeat 7 checksum += byte[++p_packet] checksum := $FF - checksum.byte[0] checksum += 1As he pointed out, if the low byte of the sum of the packet is zero, the other version would return $100 which is a 2-byte value. Silly me. Sorry for steering you wrong and grateful for my friend who pointed out a very subtle error.