Translation from Arduino code for LOFI robot app

castlerocks

New Member
Dear all,

Can you help me translate the code below to picaxe 14M2? This is to run a robot through HM-something BLE module with a LOFI Robot control app for Android and iPhone. While I got it to connect and receive serial data from the app on picaxe in minutes with SERIN command, there does not seem to be any information on actual protocol and I have trouble figuring it out with trial and error. I'm failing to follow the logic of the code to work it out from it as well, but it should be possible - it is just me and C code. This is to run a differential drive robot with two motors and a few auxiliary functions. I'm specifically interested in the part that would allow me to decode the data from the app.


Thank you for your inputs,

Edmunds


Code:
int val = 0;
int horizontal = 50;
int vertical = 50;
int A_state = 0;
int B_state = 0;
char data[5];
int m1;
int m2;

void setup()
{
    // silnik M1
    pinMode(2, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(3, OUTPUT);
    // silnik M2
    pinMode(8, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(5, OUTPUT);

    //buzzer
    pinMode(16, OUTPUT);
    // diody LED
    pinMode(10, OUTPUT);
    pinMode(9, OUTPUT);




    Serial.begin(9600); // komunikacja Arduino->Komputer przez kabel USB
    Serial1.begin(9600); // komunikacja Arduino->HM-10 bluetooth

        motor1(1, 255);
    motor2(1, 255);

}

void loop()
{


    if (Serial1.available())
    {

        Serial1.readBytes(data, 5); // odbior danych z aplikacji

        horizontal = int(data[1]); // joystick os pozioma
        vertical = int(data[2]); // joystick os pionowa
        A_state = int(data[3]); // lewy przycisk
        B_state = int(data[4]); // prawy przycisk


        horizontal = horizontal * 2 - 100;
        vertical = vertical * 2 - 100;


        Serial.print("horizontal = ");
        Serial.print(horizontal);
        Serial.print(" vertical = ");
        Serial.print(vertical);
        Serial.print(" A = ");
        Serial.print(A_state);
        Serial.print(" B = ");
        Serial.println(B_state);
    }

    digitalWrite(16, A_state);
    digitalWrite(10, B_state);
    digitalWrite(9, B_state);

    m1 = vertical - horizontal;
    m2 = vertical + horizontal;

    int mm1 = min(255, 2.7 * abs(vertical - horizontal));
    int mm2 = min(255, 2.7 * abs(vertical + horizontal));


    if (m1 > 0)
        motor1(true, mm1);
    else
        motor1(false, mm1);


    if (m2 > 0)
        motor2(true, mm2);
    else
        motor2(false, mm2);


}


void motor1(boolean direction, int power)
{
    digitalWrite(2, direction);
    digitalWrite(4, !direction);
    analogWrite(3, power);
}

// funkcja sterująca silnikiem podłączonym do gniazda M2
void motor2(boolean direction, int power)
{
    digitalWrite(7, direction);
    digitalWrite(8, !direction);
    analogWrite(5, power);
}
 

hippy

Technical Support
Staff member
Code:
   Serial1.begin(9600); // komunikacja Arduino->HM-10 bluetooth

  if (Serial1.available())
  {

        Serial1.readBytes(data, 5); // odbior danych z aplikacji

        horizontal = int(data[1]); // joystick os pozioma
        vertical = int(data[2]); // joystick os pionowa
        A_state = int(data[3]); // lewy przycisk
        B_state = int(data[4]); // prawy przycisk
That would seem to me to be reading 5 raw binary bytes so something like this would probably be a good start -
Code:
Symbol RX      = ?.?
Symbol RX_BAUD = T9600

Symbol header     = b2
Symbol horizontal = b3 ; joystick os pozioma
Symbol vertical   = b4 ; joystick os pionowa
Symbol A_state    = b5 ; lewy przycisk
Symbol B_state    = b6 ; prawy przycisk

Do
  SerIn RX, RX_BAUD, header, horizontal, vertical, A_state, B_state
  SerTxd( #header, TAB, #horizontal, TAB, #vertical, TAB, #A_state, TAB, #B_state, CR, LF )
Loop
From -
Code:
horizontal = horizontal * 2 - 100;
vertical = vertical * 2 - 100;

digitalWrite(16, A_state);
digitalWrite(10, B_state);
I would expect 'horizontal' and 'vertical' raw values to be 0 to 100, which convert to -100 to +100, and 'A_state' and 'B_state' would be 0 or 1.
 

castlerocks

New Member
Hippy, thanks a million, I had written quite exactly your code with exclusion of a header. However, thanks to trying your code, I noticed they have a header before each data byte. I don't know how that works in that Arduino code - I cannot see it there, but I'm pretty confident, I figured out the coordinate system of the joystick now. Centre is 0;0. Positive Xmax is 200 with 101 to be the first number to the right from 0. Negative Xmax is 100 with 1 to be the first number to the left from 0. Negative Ymax is 200 and positive Ymax is 100. An interesting way to handle negative numbers, actually.

Pressing "B" sends all zeroes. Since there is no other situation there would be a transmission with all zeroes, it is probably quite a clever idea. "A" is a 1, as expected. There are two more sliders, which Arduino code above does not handle, but are easy, when you know you have to skip the "header". Will see if I can post a video, if I get the thing working (the usual "camera" will be busy controlling the robot :)).

Edmunds
 

hippy

Technical Support
Staff member
I noticed they have a header before each data byte. I don't know how that works in that Arduino code - I cannot see it there
I nearly missed it as well. It was that "5" in the readBytes(), and recalling that "data[0]" would be the first byte which has me guessing it's there.

Glad you are on your way.
 

hippy

Technical Support
Staff member
@hippy: in your code you wrote Symbol RX = ?.? . What does that mean?
That specifies the pin on which the data is being received, which will depend upon your hardware, "?.?" is just a placeholder for whatever the actual value would be.

If you have the serial connected to leg 7 on your 14M2, pin C.0, that's C.0, so -
Code:
Symbol RX = C.0
 
Top