1

I've written a script in Python which sends data through the PC's Bluetooth to HC-06 on Arduino.

state is an integer from 0 to 1000 (it is controlled through the potentiometer).

...
gaugeSocket.send(str(state))
...

I can't get the right character-to-integer conversion on Arduino (from HC-06 serial).

Arduino code:

SoftwareSerial mySerial(10, 11); // RX, TX
char buf[2];
int i=0;
int data;
int ledPin = 9;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(57600);
  mySerial.begin(9600);
}

void loop() {
  if (mySerial.available()) {
    for(;i<2;){
      buf = mySerial.read();
      i++;
    }
    i = 0;
    Serial.print(buf);
    data = atoi(buf);
  }
    analogWrite(ledPin, data/10); //To see how code behaves on LED
}

Serial print gives me this (if I turn potentiometer from 0 to 1000):

0ÿ(0ÿ(0ÿ(0ÿ(0ÿ(0ÿ(0ÿ(60(1ÿ(00(16(0ÿ(23(0ÿ(30(0ÿ(3ÿ(60(43(0ÿ(49(0ÿ(53(0ÿ(5ÿ(90(69(0ÿ(88(0ÿ(10(00(10(00(10(

What am I missing? Is it because I'm sending it as a string? Or is my buffer not the correct size?

1

Here is your main problem:

if (mySerial.available()) {
    for(;i < 2;){
        buf = mySerial.read();
        i++;
    }
....

There you are saying "If there is at least one character available in the buffer then read lots of characters from the buffer".

You can't read characters that aren't there yet.

So your stream of data is interspersed with the integer -1 which means "I don't have any data to read!"

I explain it all here: http://hacking.majenko.co.uk/reading-serial-on-the-arduino

By the way - character -1 looks like this: ÿ

You are sending your data as text. That means, to send the value 348 you are first sending the byte representation of the ASCII character "3", which is the decimal byte value 51. Then you send the byte representation of the ASCII character "4", which is the decimal value 52, and finally you send the byte representation of the ASCII character "8", which is the decimal value 56.

You look to see if there is one byte available (if(mySerial.available())) and then read that byte into "buf" and increment "i" (by the way, "i" is never reset to 0 - your whole loop strategy is completely wrong, but that's a completely different issue). You then read a second character and assign that to buf instead.

So if you have the character "3" in the serial buffer you then place that in "buf". You then read whatever is next in the buffer, which 9 times out of 10 will be nothing, so read() returns -1. So you just assign that to "buf" instead, replacing the "3" that was in there before.

But "buf" is a character array, and you are assigning a character to the whole array, which makes absolutely no sense (does the code even compile as you have shown it?).

Basically your whole reading routine is completely wrong and can never work no matter how much tweaking and advising we do.

The link I provided above describes not only how you should do the reading on the Arduino, but also how you should do the sending from the other end. It is vitally important that you send something that says "This is the end of the number I am sending" so that the Arduino knows where one number ends and the next starts. Normally that is done, when sending a textual representation of the number like this, by adding a line feed and/or carriage return at the end of your number. So instead of sending "348" you send "248\n".

The Arduino then checks to see if there is one character available, and then it adds just that one character to the end of the buffer. If, and only if, that character is the delimiting character then you can take the buffer and translate it into an actual number and reset your buffer to be empty ready to receive the next number.

The link above has good example code showing you exactly how to do that.

  • Thanks, that was really helpful. But I still can't get it going. If I'm sending numbers from 0-1000, that means I'm sending 2 bytes. And when I want to read it like if(mySerial.available() >= 2) it's still a mess. Would you please be so kind to help me directly on this one? – Electruc Sep 17 '15 at 11:18
  • Only if you're sending it as bytes. You're sending it as text though so it is between 1 and 4 bytes plus whatever you delimit with. – Majenko Sep 17 '15 at 11:44
0

Use itoa instead of str.

str just converts the byte to an ASCII character. So 48 will become '0', 195 will become 'ÿ', and 191 will become '('.

0

I think you should check your baud rates. A mismatch in baud rates usually makes that symbol get printed on the screen.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.