MIT app inventor and Arduino

Im working on a project for myself that will allow me to change some variables stored on an arduino through bluetooth and my andoid phone. I have the arduino side working perfectly when I use the app BlueTerm on my phone. I can connect over bluetooth and send a string such as <3,200> and my arduino code looks for a start of frame "<" and end of frame ">" and split the data up into 2 variables. Now onto the issue...

Im using MIT app inventor to create a custom app to send the data to my arduino, I have bluetooth also working with app inventor for the most part but im having trouble sending the data in the proper format. I only have a couple options in the MIT software as to how I send the data, I can "SendText" or I can "Send1ByteNumber"

The closest I have gotten to having this work is by using the following code:

BluetoothClient1.SendText(<)
BluetoothClient1.Send1ByteNumber(3)
BluetoothClient1.SendText(,)
BluetoothClient1.SendSend1ByteNumber(200)
BluetoothClient1.SendText(>)

On the Arduino side my code recognizes the <, > and , but not the numbers. This is what I am getting in the SerialMonitor

à,È

Im pretty sure this is just an issue with the numbers being sent in one format and recived / processed in another but I have no idea where to go from here.

Send1ByteNumber is probably sending the binary value which isn't what you want.
Since you can already send a string such as "<3,200>", all you need is BluetoothClient1.SendText(<3,200>)

Pete

Should have mentioned that in my first post...I have tried SendText(<2,300>)

The code on my arduino does not even see the start of frame "<" or end of frame ">" when I send data like that from the MIT app inventor

Here is the Arduino code that I put together with a couple guys on this forum that works with Blueterm but not MIT app inventor.

#define SOP '<'            //packet markers for bluetooth comms
#define EOP '>'

while(bluetooth.available() > 0)            
  {
    char inChar = bluetooth.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }

  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet
    Serial.println(inData);
    bluetooth.println(inData);
    
    char *token = strtok(inData, ",");      //proccess inData into variables
    if(token)
    {
      command = atoi(token);
      token = strtok(NULL, ",");
    }
    if(token)
    {
      value1 = atoi(token);
    }
  }

What is getting to the Arduino? If it is not recognizable data, then the if conditions will never be true. Print each character that arrives. Is it what you expect?

starting from scratch with a blank sketch using following code

while(bluetooth.available() > 0)
  {
    Serial.println(bluetooth.read());
  }

And the following command in App Inventor

BluetoothClient1.SendText(<3,200>)

Displays this in the serial monitor

60
38
73
130
193
249
255

60 is ascii for < but the rest is garbage to me.

I get a better response sending data like this

BluetoothClient1.SendText(<)
BluetoothClient1.Send1ByteNumber(3)
BluetoothClient1.SendText(,)
BluetoothClient1.SendSend1ByteNumber(200)
BluetoothClient1.SendText(>)

Serial monitor

60
224
44
200
62

60, 44, and 62 are the < , and > characters but the 224 is throwing me off. Most of the time the serial monitor will display the 2nd number correctly but not always and more often the first number changes. just changed my App Inventor code to send 10 and 2 and got two different outputs from the serial monitor.

60
133
44
2
62

60
133
44
129
62

The only setup options I have for the bluetooth in App inventor is "Character Encoding" and "DelimiterByte" those are set to UTF-8 and 0

Im thinking I need to drop this App Inventor stuff and just learn the android SDK w/ eclipse

I realize this thread is over a year old but I ran into a similar problem and found a solution; I thought I should post it in case someone is encountering the same issue.

In MIT app inventor have the output set to the numbers you want to output their ASCII code
ex if you wanted to send the number '1' use:

BluetoothClient1.Send1ByteNumber(49)

49 is the ASCII code for '1'

This will be received by the arduino as '1' not as '49'

so for your original code I would think that this should work (at least something similar did for me):

BluetoothClient1.SendText(<)
BluetoothClient1.Send1ByteNumber(51)
BluetoothClient1.SendText(,)
BluetoothClient1.SendSend1ByteNumber(È)
BluetoothClient1.SendText(>)

and the output should be <3,200>

note - you can find decimal to ASCII converters online for free just google "decimal to ASCII converter" - I had to do this to find that "È" is ASCII for "200"

Hope this helps!

Thank You! I am that person you just helped!

earthshaker495:
I realize this thread is over a year old but I ran into a similar problem and found a solution; I thought I should post it in case someone is encountering the same issue.

In MIT app inventor have the output set to the numbers you want to output their ASCII code
ex if you wanted to send the number '1' use:

BluetoothClient1.Send1ByteNumber(49)

49 is the ASCII code for '1'

This will be received by the arduino as '1' not as '49'

so for your original code I would think that this should work (at least something similar did for me):

BluetoothClient1.SendText(<)
BluetoothClient1.Send1ByteNumber(51)
BluetoothClient1.SendText(,)
BluetoothClient1.SendSend1ByteNumber(È)
BluetoothClient1.SendText(>)

and the output should be <3,200>

note - you can find decimal to ASCII converters online for free just google "decimal to ASCII converter" - I had to do this to find that "È" is ASCII for "200"

Hope this helps!

Hi everyone,

Thanks for all the good suggestions in this thread. It helped me to solve at least part of the problem.

I have a similar problem with appinventor stated in the thread. My Arduino code is working perfectly with Blueterm and Putty, but not with appinventor. After reading this thread I modified my appinventor code, by sending bytes to Arduino as suggested above.

Basically, I want to control a motor with appinventor, by sending a gcode string such as G1 X5 S1; So my blocks are as following

BluetoothClient1.SendText(G)
BluetoothClient1.Send1ByteNumber(49)
BluetoothClient1.SendText()
BluetoothClient1.SendSend1ByteNumber(X)
BluetoothClient1.SendText(53)
BluetoothClient1.SendText()
BluetoothClient1.SendText(S)
BluetoothClient1.SendSend1ByteNumber(49)
BluetoothClient1.SendText(:wink:

This is received by Arduino as G1 X5 S1; as expected by Arduino does not parse it as it would with a same command received from Blueterm. I cant understand where the problem is. My arduino code is following. Could you please help me.

Many thanks.

 #include <Stepper.h>
#define FULLSTEP 4
#define HALFSTEP 8
#define motorPin1  13
#define motorPin2  11    // Pink   - 28BYJ48 pin 2
#define motorPin3  10   // Yellow - 28BYJ48 pin 3
#define motorPin4  9
#define THREADED_ROD_PITCH 1.25
#define STEPS_PER_REVOLUTION 200.0
#define MICROSTEPS_PER_STEP 16.0
#define MAX_BUF (64)
#define STEPS_PER_OUTPUT_REVOLUTION  MICROSTEPS_PER_STEP * STEPS_PER_REVOLUTION
Stepper stepper(STEPS_PER_OUTPUT_REVOLUTION, motorPin1, motorPin3, motorPin2, motorPin4);
int motorSpeed = 25; // Maximum steps per second (about 3rps / at 16 microsteps)
int travelSpeed = 1000; // max speed for fast travel // G0

char buffer[MAX_BUF];  // where we store the message until we get a newline
int sofar;  // how much is in the buffer


void pause(long ms) {
  delay(ms/1000);
  delayMicroseconds(ms%1000);  // delayMicroseconds doesn't work for values > ~16k.
}

int parsenumber(char c, int val ) {

  //unfinished
  String tempCharString = "";
  boolean isNegative = false;

  for (int i = 0; i < MAX_BUF; i++)
  {
    if (buffer[i] == c)
    {
      while (buffer[i] != ' ')
      {
        i++;
        //        if(buffer[i] == '-')
        //          isNegative = true;
        //        else
        tempCharString += buffer[i];
      }
      //      if(isNegative)
      //        return tempCharString.toInt()*-1;
      //      else
      return tempCharString.toInt();

    }
  }
  return val;
    Serial.print("val"); 
      Serial.print(val); 

  //G00 S900 X200

}
 



void help() {
  Serial.print(F("GcodeCNCDemo2AxisV1 "));

}


/**
 * Read the input buffer and find any recognized commands.  One G or M command per line.
 */
void processCommand() {
  int posTemp = 0;
  int sp=0;
  int dir=1;
 // Serial.print(buffer);

  int cmd = parsenumber('G',-1);
  switch(cmd) {
  case  0:{ // line
    posTemp = parsenumber('X', -1);
    sp= parsenumber('S', -1); //get speed
    stepper.setSpeed(sp);
    dir = parsenumber('D', -1);   
     if (dir==0)
        posTemp=-1*posTemp;   
    stepper.setSpeed(travelSpeed);
    stepper.step(posTemp);
    Serial.print("posTemp"); 
    Serial.print(posTemp); 
    Serial.print("ZERO"); 
    break;
    }
  case  1: { // line
    posTemp = parsenumber('X', -1);
    sp= parsenumber('S', -1); //get speed
    stepper.setSpeed(sp);
    dir = parsenumber('D', -1);   
     if (dir==0)
        posTemp=-1*posTemp;   
    stepper.setSpeed(sp);
    stepper.step(posTemp);
    Serial.print("sp"); 
    Serial.print(sp); 
    Serial.print("posTemp"); 
    Serial.print(posTemp); 
    Serial.print("ONE"); 
    break;
    }
  
  default:  break;
  }
}

 


/**
 * prepares the input buffer to receive a new message and tells the serial connected device it is ready for more.
 */
void ready() {
  sofar=0;  // clear input buffer
  Serial.print(F(">"));  // signal ready to receive input
}


/**
 * First thing this machine does on startup.  Runs only once.
 */
void setup() {
  Serial.begin(9600);  // open coms
 help();  // say hello
  ready();
}


/**
 * After setup() this machine will repeat loop() forever.
 */
void loop() {
  // listen for serial commands
  while(Serial.available() > 0) {  // if something is available
    char c=Serial.read();  // get it
    Serial.print(c);  // repeat it back so I know you got the message
    if(sofar<MAX_BUF-1) buffer[sofar++]=c;  // store it
    if((c=='\n') || (c == '\r')) {
      // entire message received
      buffer[sofar]=0;  // end the buffer so string functions work right
      Serial.print(F("\r\n"));  // echo a return character for humans
      processCommand();  // do something with the command
      ready();
    }
  }
}

This is received by Arduino as G1 X5 S1; as expected by Arduino does not parse it as it would with a same command received from Blueterm. I cant understand where the problem is.

I'm going to presume that "as expected by Arduino" was supposed to be "as expected, but Arduino".

My arduino code is following.

Properly posted code is great. Thank you for posting all of it, in code tags.

But, (you knew there was going to be one, didn't you?) there is no serial output, so we have no way of validating your claim.

Having taken proper care to collect the data in a char array, I'm disappointed to see the use of Strings in the parsing routine. The strtok() function can parse a string. The sscanf() function could be used to collect all three values from the string, and return the appropriate one. Neither approach requires the use of the String class OR re-inventing the wheel.

  return val;
    Serial.print("val");
      Serial.print(val);

Trying to do anything after a return statement is pointless, don't you think?

Hi Paul,

Many thanks for your kind reply.

  1. Yes, your presumption is correct. I am neither good at English nor coding. I am trying my best to hack the codes I get online.

  2. Sorry, I did not think about posting the output. Please see the attached pic to this post.
    In the console, I get the following output

>GcodeCNCDemo2AxisV1 >G1 X100 S1;
sp1posTemp100ONE>G1 X5 S1;
sp1posTemp5ONE>G1 X5 S1;G1  X-100 S1;G1 X5 S1;G1 X5 S1;G1 X5 S1;

The first output is a result of me typing in Putty directly. I can see what I typed(G1 X100 S1;) and also sp1 indicates the speed and posTemp100 indicates the steps. So it actually parsed the code, I can see also LED blinking on PIN 13. Also > indicates that Arduino is ready to take a new command.

Second output is a result of typing from Blueterm. As above, I can still see blinking and everything as expected. I can see > command again.

Third output is the result from app inventor. Its clear that Arduino has received the code, as it reprinted the code on screen. But its not parsed, as I cannot see the > command and no blinking. I see same code (G1 X5 S1;) again and again as I was pressing that corresponding button on app many types.

  1. I really don't know how to use the functions strtok() and sscanf(). As I mentioned previously, I am just using a code, I got from a website.

Thanks again for your help.

demo_pic2.png

Could any one please point me to any resource.

The first output is a result of me typing in Putty directly. I can see what I typed(G1 X100 S1;) and also sp1 indicates the speed and posTemp100 indicates the steps. So it actually parsed the code, I can see also LED blinking on PIN 13. Also > indicates that Arduino is ready to take a new command.

I find it very difficult to see that. Anonymous printing sucks.

Serial.print("Input: [");
Serial.print(buffer);
Serial.println("]");

conveys so much more information.

Third output is the result from app inventor. Its clear that Arduino has received the code, as it reprinted the code on screen. But its not parsed,

I suspect that is because app inventor is not sending the carriage return and line feed that the Arduino expects, to know when input is complete.