Interpreting the value I receive from the ATDB command for Xbee S2 - xbee

I realize that this might be the stupidest question that has ever been asked here, but I'm really stuck. I am trying to get the RSSI value of an XBee router so I send ATBD from the coordinator. The value returned is in hexadecimal but I cannot, for the life of me, see how that hexadecimal value interprets as a dBm value.

Actually the command isn't ATBD, but ATDB, which means:
"Received Signal Strength. This command reports the received signal strength of the last received RF data packet. The DB command only indicates the signal strength of the last hop. It does not provide an accurate quality measurement for a multihop link. DB can be set to 0 to clear it. The DB command value is measured in -dBm. For example if DB returns 0x50, then the RSSI of the last packet received was -80dBm. As of 2x6x firmware, the DB command value is also updated when an APS acknowledgment is received." (Retired from XBee ZB User Manual p.131).
As you can see the example above, you just need to:
Read the Hexadecimal (example: 0x50)
read it as decimal (example: 0x50 = 80 in decimal)
multiply by -1: (-1)*80 = -80 dBm
The ATBD command is used to change the serial interface data rate (baud rate).

Related

C code to Read data from nonin Pulse Oximeter device via bluetooth Serial Port profile in linux

I am trying to communicate to the Nonin Pulse oximeter device to read the data (Pulse rate and SPO2 level) via Bluetooth. Nonin device supports SPP and HDP profile. I want to communicate through SPP profile. I am able to scan and pair with the device by the sample code available in Bluez.
Please tell me next steps how to send command and read data from the device. I have got struck at this point.
I realize this is a late response, but I recently setup data acquisition from a Nonin PalmSAT 2500A VET unit. I am using the RTC-1000 cable and an RS232 to USB converter.
This is straight from the manual:
"Information from the device, in the real-time mode, is sent in an ASCII serial format at 9600 baud with 9 data bits, 1 start bit, and 1 stop bit. The data are output at a rate of once per second.
NOTE: The 9th data bit is used for odd parity in memory playback mode. In real-time mode, it is always set to the mark condition. Therefore the real-time data may be read as 8 data bits, no parity.
Real-time data may be printed or displayed by devices other than the pulse oximeter. On power up a header is sent identifying the format and the time and date. Thereafter, the data are sent once per second in the following format:
SPO2=XXX HR=YYY
where “XXX” represents the SpO2 value, and “YYY” represents the pulse rate. The SpO2 and pulse rate will be displayed as “---” if there are no data available for the data reading."
Link to manual:
http://www.proactmedical.co.uk/proshop_support_docs/2500aman.pdf
What model oximeter are you working with?

Linux serial port reading in asynchronized mode

I have a trouble in reading datas from serial in Linux system. I am trying to connect a sensor with the linux system by using UART. I can read and write /deve/ttyS1. But the problem is that I dont want to poll the message from UART. Instead, I want to use the asynchronized mode to get the data. As the data comes, the call back function will enter a certain routine and run my code. The problem no is that the sensor sends me different packets and each one contains various bytes of data. They are coming every one second!
For example:
Time Sensor MyLinux
1s 50bytes
124bytes
2s 40bytes
174bytes
3s 60bytes
244bytes
My question is how to use the asynch serial programming so that in the call back function, those two packets can be read as two messages
say
50 bytes comes, the call back function can let me read 50 bytes
127 bytes comes, the call back function can let me read 127 bytes
Now, its like, 50 bytes comes, I can only read 27bytes, and the rest 23 are in the next message.
My setting for serial port in POSIX is:
/* now we setup the values in port's termios */
serial->tio.c_cflag=baudrate|databits|checkparity|stopbits|CLOCAL|CREAD;
serial->tio.c_iflag=IGNPAR;
serial->tio.c_oflag=0;
serial->tio.c_lflag=0;
serial->tio.c_cc[VMIN]=28;
serial->tio.c_cc[VTIME]=6;
/* we flush the port */
tcflush(serial->fd,TCOFLUSH);
tcflush(serial->fd,TCIFLUSH);
/* we send new config to the port */
tcsetattr(serial->fd,TCSANOW,&(serial->tio));
Try to set VMIN and VTIME at following values:
serial->tio.c_cc[VMIN]=0;
serial->tio.c_cc[VTIME]=1;
Then you'll come out of select() after reading a complete chunk of data from your sensor. If the number of bytes is less, than you've expected, you can set timeout for select and read the data once more appending to your current buffer. If you get data before the timeout, then you have your complete message.

libusb: libusb_control_transfer freezing the program

I am trying to get the firmware version of my usb device. As per the specification:
When using the USB interface, the commands are sent as CONTROL READ requests, where the request byte is the command, and the Index and Value are additional parameters sent to the Device. If the PC is requesting data, it will be returned in the endpoint 0 IN buffer.
Command Description Device Response / Notes
a Request firmware version The device returns 4 bytes containing the version number in ASCII.
Now to request firmware version, I do the following:
char buffer[4];
unsigned char a = 'a';
r = libusb_control_transfer(dev_handle,0,a,0,0,buffer,4,0);
But the program stops responding, and I can't get any result.
There are two things I see that could be wrong here:
The character value 'a' is equal to 0x61, I think what you want is 0x0A for your bRequest parameter.
Also, since you are getting data from the device you probably want to setup bmRequestType properly. 0x80 is the mask that represents data going from the device to the host, right now you are specifying that you are giving data to the device.
In these cases a USB analyzer is highly useful, so you can look at the bus to get an idea of exactly what the setup packet contains that is sent to your device as well as what it's response to the host is.
Here is the modified code:
char buffer[4];
r = libusb_control_transfer(dev_handle,0x80,0x0a,0,0,buffer,4,0);

Need some help on Serial Port Transmission

i'm currently using DS89C450 MCU on Keil C51 Programming.
I have an Infrared Receiver attached to P3^2 which is the falling edge trigger. Whenever I press a key on the remote control, it will trigger the interrupt and save it into the xdata X or Y (bit by bit then byte by byte for 500 bytes).
I'm trying to transmit the data bit (either '1' or '0') from the buffer to the hyperterminal via Serial Port. However, I do not get any data displayed when I press the remote control.
Can anyone expert tell me why and how do i get it to work?
The program is here:
http://pastebin.com/hpAw2ipH
Google "Terminal by br#y", it can show serial comms in HEX. Most UARTs cannot send a single bit, rather they will send a character of N bits, usually 7 or 8, with start/stop/parity bits (8-bits, no parity, 1 stop bit being the universal default). It can make life easier to encode data as ASCII, perhaps even with start/stop characters, so you know when you're getting real data.
For even more detail, use an oscilloscope, BusPirate or LogicSniffer (from DangerousPrototypes.com) to sniff the communications data.

Serial programming: measuring time between characters

I am sending/receiving data over a serial line in Linux and I would like to find the delay between characters.
Modbus uses a 3.5 character delay to detect message frame boundaries. If there is more than a 1.5 character delay, the message frame is declared incomplete.
I'm writing a quick program in C which is basically
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
// setup newtio
....
tcsetattr(fd, TCSANOW, &newtio);
for(;;) {
res = read(fs, buf, 1);
if (res > 0) {
// store time in milliseconds?
//do stuff
}
}
Is there some way of measuring the time here? Or do I need to look at retrieving data from the serial line in a different way?
I've also tried hooking into SIGIO to get a signal whenever there is data but I seem to get data 8 bytes at a time.
(yes, I know there exist some modbus libraries but I want to use this in other applications)
The simple answer is... you cannot (not without writing you own serial driver)!
If you are writing a MODBUS master there is some hope: You can either detect the end of a slave response by waiting any amount of time (provided its longer than 3.5 chars) without receiving anything (select(2) can help you here), or by parsing the response on the fly, as you read it (the second method wastes much less time). You must also be careful to wait at least 3.5 characters-time before staring to transmit a new request, after receiving the response to the previous request. "At least" is operative here! Waiting more doesn't matter. Waiting less does.
If you a writing a MODBUS slave then you' re out of luck. You simply cannot do it reliably from userspace Linux. You have to write you own serial driver.
BTW, this is not Linux's fault. This is due to the unbelievable stupidity of MODBUS's framing method.
MODbus is like a lot of old protocols and really hates modern hardware.
The reason you're getting 8 bytes at a time is :
Your PC has a (at least) 16 byte serial FIFO on receive and transmit, in the hardware. Most are 64byte or bigger.
It is possible to tell the uart device to time out and issue a received interrupt after a number of char times.
The Trigger Level is adjustable, but the low-level driver sets it "smartly". try low-latency mode using setserial)
You can fiddle with the code in the serial driver if you must. Google it (mature content warning) it is not pretty.
so the routine is as pseudocode
int actual=read (packet, timeout of 1.5 chars)
look at actual # of received bytes
if less than a packet, has issues, discard.
not great.
You can't use timeouts. On higher baud rates 3.5 character timeout means a few milliseconds, or even hundreds of microseconds. Such timeouts can't be handled in the Linux user space.
On the client side, it isn't a big deal since Modbus doesn't send asynchronous messages. So it's up to you not to send 2 consecutive messages within 3.5 character timeout.
On the server side, the problem is that if your clients have an extremely short response timeouts and Linux is too busy you can't write a bullet-proof framing solution. There is a chance that read() function will return more than one packet. Here is (a little contrived) example.
Client writes a packet to server. Timeout is let's say 20 ms.
Let's say that Linux is at the moment very busy, so kernel doesn't wake up your thread within next 50 ms.
After 20 ms client detects that it didn't receive any response so it sends another packet to server (maybe resent the previous one).
If Linux wakes up your reading thread after 50 ms, read() function can get 2 packets or even 1 and half depending to how many bytes were received by the serial port driver.
In my implementation I use a simple method that tries to parse bytes on-the-fly - first detecting the function code and then I try to read all remaining bytes for a specific function. If I get one and half packet I parse just the first one and remaining bytes are left in the buffer. If more bytes come within a short timeout I add them and try to parse, otherwise I discard them. It's not a perfect solution (for instance some sub-codes for function 8 doesn't have a fixed size) but since MODBUS RTU doesn't have any STX ETX characters, it's the best one I were able to figure out.
I think you are going about this the wrong way. There is a built in mechanism for ensuring that characters come in all together.
Basically, you are going to want to use ioctl() and set the VMIN and VTIME parameters appropriately. In this case, it seems like you'd want VMIN (minimum number of characters in a packet) to be 0 and VTIME (minimum amount of time allowed between characters to be 15 (they are tenths of seconds).
Some really basic example code:
struct termio t;
t.c_cc[ VMIN ] = 0;
t.c_cc[ VTIME ] = 15;
if (ioctl( fd, TCSETAW, &t ) == -1)
{
printf( msg, "ioctl(set) failed on port %s. Exiting...", yourPort);
exit( 1 );
}
Do this before your open() but before your read(). Here's a couple of links that I've found wildly helpful:
Serial Programming Guide
Understanding VMIN and VMAX
I hope that at least helps/points you in the right direction even if it isn't a perfect answer for your question.

Resources