SV328 UART RX from Ultrasonic Rangefinder

Hi,
I am about as new to this as it gets, I am using the SV328 Orangutan board to receive a distance reading from a Ultrasonic Rangefinder. Please refer to the code below:

[code]#include <pololu/orangutan.h>

int main()
{
int receive_buffer[4];
serial_set_baud_rate(9600);
serial_receive_ring((char *) receive_buffer, 4);

while(1){
long distance=receive_buffer[1]*256 + receive_buffer[2]; /*add the second and third byte of the array which represents the distance in millimeters with the second byte being highest byte and the third being the lowest byte*/
lcd_goto_xy(0,0);
print_long(distance);
	}

return 0;

}
[/code]
The packet sent from the rangefinder has the distance in the second and third byte in mm. This code compiles and I seem to be getting random numbers. The rangefinder I am using is from core electronics with the data sheet here: sure-electronics.net/downloa … Manual.pdf

I feel like a goose, and I know that the error is in my basic understanding of programming. However, I have spend days on this and am now stuck. Can you please help?

Hi.

Did you write that code yourself? If not, could you tell me where you got it? Could you post some pictures and a wiring diagram of your setup?

Could you try printing out all 4 of the raw bytes to a terminal program on your computer and posting that data here? This would involve using your programmer as a USB-to-serial adapter, connecting the OUT pin of your Ultrasonic sensor to the RX line of your Orangutan SV-328, and connecting the TX line of the SV-328 to your programmer. If you are not comfortable trying this, could you print all 4 of the raw bytes to the LCD?

- Zeeshan

Your code doesn’t check that bytes are actually received from the serial port, and it doesn’t check for the integrity of the basic packet sent by the sonar sensor, which is supposed to consist of four bytes 0xFF, data1, data2, checksum (= data1+data2).

It would probably be easier for you to use the serial_receive_blocking function (which if set up properly, will return when 4 bytes are received) instead of the serial_receive_ring function.
Try something like this (untested code)!

    char buffer[4],timeout;
    // the following inside the main loop
    timeout = serial_receive_blocking(buffer,4,1000);
    if (timeout == 0) { 
            //4 bytes received, check if valid
	    if ( (buffer[0] == 0xff) && (buffer[3] == buffer[1] + buffer[2]) ) {
	        //valid packet, process data
	       }
	    else {
		//invalid packet, print warning
		}
    else  if (timeout != 0 ) {
	// 1000 ms timeout on serial port, print warning
	  }
    }

BTW the documentation for that sonar unit is about as minimal as one could imagine. How do you guess that the data format is TTL serial at 9600 baud? It might be a few bucks cheaper than the competition, but in my view you aren’t saving yourself trouble.

Hi,

Thanks for your replies, the code is my own, derived from studying the various resources found on the pololu website. I tried printing off the first byte of information and got 0xEC after amending the code to output in hex.

I placed the setup on a CRO this morning and found that the operating range of the TTL was 0-2V which I don’t think is large enough for the SV-328 to recognise??


I would prefer not to print to a terminal on the computer as that would mean more hours sifting through the references trying to work out how to do it!

Jim, I did initiailly try the blocking function, at the time I was just trying to get something on the screen. Thanks for your code, I will give that a go tonight and see what happens.

I cannot find anywhere in the documentation, what the voltage range is of the TTL on the SV328, I assume that if it is 0-5V, the 0-2V that is being sent from the rangefinder is too low.

The SV328 is supposed to detect a high if the input voltage is > 0.6*Vcc or 3.0 V (look under “Electrical Characteristics” towards the end of the ATmega328 data sheet). So, 2.0 V from the sonar definitely won’t work. But if you are powering the sonar with 5.0 V and seeing 2.0 V on the output, something else is probably wrong.

Do you have all grounds connected together and a direct connection (a wire) between the sonar output pin and the SV328 input pin?

Do you see 2.0 V on the sonar output if it is disconnected from the SV328?

It is conceivable that the sonar output is “open collector” or “open drain”. If so (and this won’t hurt in any case) try connecting a 10 Kohm resistor between 5 V and the sonar output pin, while also connected to the SV328 input pin. That should pull up the voltage to operating levels for the 328. You could also try enabling the internal pullup resistors on the SV328.

Guys,

I have been in contact with the distributor of the sensor and they have informed me that it is designed to work off 2V high. Even with the pull up resistor enabled it still did not get to 3V. I informed them of this and they offered to give me a full refund. I have since purchased a maxbotics item and have everything running nicely.

Thanks again for your help and advice!

I wonder what the board designer was thinking.