Can someone please help me with this code ?

Hi there,

Sorry if this a wrong section. But I hope its the right one, since it’s about Bluetooth Byte Read.

Basically, I found an old tutorial using arduino with Bluetooth Low Energy module to control an RC car with iPhone.

The iPhone app is using 2 sliders ( Foward / Reverse ) & ( Left / Right Directions )

The both sliders output values in from

-255 ← 0 → 255

0 is stall.

The original author’s video:

Here is the arduino code:
Carduino/Carduino_iOS.ino at master · Ladvien/Carduino · GitHub

RAW CODE:

//I've been using Zombie_3_6_RC in Processing to interact.
// Record any errors that may occur in the compass.
int error = 0;

//int pwm_a = 10; //PWM control for motor outputs 1 and 2 is on digital pin 10
int pwm_a = 3;  //PWM control for motor outputs 1 and 2 is on digital pin 3
int pwm_b = 11;  //PWM control for motor outputs 3 and 4 is on digital pin 11
int dir_a = 12;  //dir control for motor outputs 1 and 2 is on digital pin 12
int dir_b = 13;  //dir control for motor outputs 3 and 4 is on digital pin 13

int lowspeed = 120;
int highspeed = 140;

//Distance away
int distance;

//Sets the duration each keystroke captures the motors.
int keyDuration = 10;

int iComp;

char parseStream[3];
int parseStreamIndex = 0;

int motorPwmA;
int motorPwmB;

boolean motorDirA;
boolean motorDirB;

void setup()
{
  Serial.begin(115200);
  delay(100);
  Serial.println("Connected correctly...");

  pinMode(pwm_a, OUTPUT);  //Set control pins to be outputs
  pinMode(pwm_b, OUTPUT);
  pinMode(dir_a, OUTPUT);
  pinMode(dir_b, OUTPUT);
  
  analogWrite(pwm_a, 0);        
  //set both motors to run at (100/255 = 39)% duty cycle (slow)  
  analogWrite(pwm_b, 0);

  pinMode (2,OUTPUT);//attach pin 2 to vcc
  pinMode (5,OUTPUT);//attach pin 5 to GND
  // initialize serial communication:

  
}

void loop()
{

  delay(10); //For serial stability.
  
  char val = Serial.read();// - '0';
   
   parseStream[parseStreamIndex] = val;
   
   if(val > -1)
   {
     if(val == ':')
     {
        int int1 = parseStream[0];
        int int2 = parseStream[1];
        int int3 = parseStream[2];
        int int4 = parseStream[3];
        
        if (int4 == 58){
            // CONTROL BYTE
            //  BIT: 7=CAN'T BE USED
            //  BIT: 6=
            //  BIT: 5=Breaklights ON
            //  BIT: 4=Headlights ON
            //  BIT: 3=127+ MOTOR B
            //  BIT: 2=127+ MOTOR A
            //  BIT: 1=MOTOR B DIR
            //  BIT: 0=MOTOR A DIR
          
          if ((bitRead(int1, 0)) == 1)
          {
           //Serial.print(" A Forward "); 
           motorDirA = true;
          }
          if ((bitRead(int1, 1)) == 1)
          {
           //Serial.print(" B Forward "); 
           motorDirB = true;
          }
          if ((bitRead(int1, 2)) == 1)
          {
            int2 = int2 + 127;
          }
          if ((bitRead(int1, 3)) == 1)
          {
            int3 = int3 + 127;
          }
          /*
          Serial.print("One: ");
          Serial.print(int1);
          Serial.print(" Two: ");
          Serial.print(int2);
          Serial.print(" Three: ");
          Serial.print(int3);
          Serial.print(" Four: ");
          Serial.println(int4);
         */
         Serial.write(0x06);
          motorPwmA = int2;
          motorPwmB = int3;
          
          drive();
          //delay(10);
          motorDirA = false;
          motorDirB = false;
        }
          parseStreamIndex = -1;               
     }
     parseStreamIndex++;
   }
}   

//boolean motorDirA, boolean motorDirB, int motorPwmA, int motorPwmB

void drive(){
//Straight back
      analogWrite(pwm_a, motorPwmA);      
      analogWrite(pwm_b, motorPwmB);
  
      digitalWrite(dir_a, motorDirA);  //Reverse motor direction, 1 high, 2 low
      digitalWrite(dir_b, motorDirB);  //Reverse motor direction, 3 low, 4 high
      while(Serial.read() != -1 );
//delay(keyDuration);
}

The arduino code that was shared by the original aurthor is made for a 2 Wheel Chassis Robot kit. which means… The chassis kit has 2 dc motors to turn and move the robot.

But my project is made based on a cheap RC car which has 2 DC motors, one is for direction ( No servo ) and other one for moving forward and reverse.

I uploaded and tested the code. It works fine for reverse… but when I move the slider foward/up. The motor spins for a second and stops when the slider value is at -255.

Why is that ? Is it because the code is originally designed for 2 Wheel powered motor robot or something else wrong ?

Rest works fine but only problem is when the slider reaches -255 level the motor stops.

I’d really appreciate if someone could help me with a simple code or fix this existing code for my current RC setup as mentioned above…

Looking forward for your reply.

Many thanks in advance.

PS: I contacted the original author, But no response.

      while(Serial.read() != -1 );

What happens when Serial.read() actually reads something? The value is not -1, so the while loop ends. The value, however, is lost. That looks to me like it matters. You can use Serial.peak() to see what there is to read, without actually reading it, or, better yet, use Serial.available() to see if there is anything to read, without caring what that is.

Sorry Im not sure what you mean.. But If I'm right.. When it reads a value, the motor starts to spin.

0 to -255 ( negative ) is anti-clock wise ( forward )

0 to 255 ( positive ) is clock wise ( reverse )

that's how the values are being sent from the iphone app to arduino via BLE module.

The motor actually works when you move the slider in-between these 2 values ( 0 to -255 ) like around -120 value..the motor spins slowly and stops when the slider reach the value of -255.

Sorry Im not sure what you mean.. But If I'm right.. When it reads a value, the motor starts to spin.

The first packet arrives. It contains 4 bytes and a :. You store the 4 bytes and the : in the first 5 elements of parseStream, which is only sized to hold three.

Because the packet ended with a :, you use the first 4 values (of the three that there was room to store).

Then, you read, and throw away, data from the serial port, until you have read and thrown away a valid value.

Then, you read the rest of the packet, stopping when the next : arrives.

Now, the byte that was supposed to be in parseStream[ 0 ] was thrown away, so the value that is actually there is the one that was supposed to be in parseStream[ 1 ]. The value that was supposed to be in 2 is now in 1, and the value that was supposed to be in 3 is in 2. The value that was supposed to be in 4 (the ':') is now in 3.

When you use, blindly, the data that is in parseStream, the values are not at all what you expect.

So, after the first packet, you get nothing but junk, because you have thrown away some good data.