Project in progress
Control MeArm Robot With MKR1000 And Your Smartphone

Control MeArm Robot With MKR1000 And Your Smartphone © CC BY-SA

This project allows you to control a MeArm Robot with your smartphone, as if you had many potentiometers in your hands.

  • 597 views
  • 1 comment
  • 6 respects

Components and supplies

About this project

At first, I wanted to train myself to the wifi network thanks to Arduino ... to quickly put myself in mind to control a robot.

In the set of projects I've found that already allow to do it, it is asked to appeal to the apps, the shields, or to click on links in web pages ....

I wanted to create something more functional, which allows to easily control the motors on the robot, to the nearest step.

in addition, not wanting to overload the small mkr1000 card in code or wiring, I decided to split the code into 2 parts: a master part (mkr1000) receiving the instructions from the web page, and a slave part (arduino Uno) controlling the motors and the LCD display. This allows you to display text, as well as to display the requested motor and angle commands as a relay.

The communication between the 2 cards uses the I2C protocol, since I could not find a way to use RT / TX.

Finally, the LED located on the original mkr1000 card will be used to indicate whether or not a wifi client is connected.

You will notice that the Serial link with the MKR1000 module must be started live on a PC so that the whole assembly can work properly. Moreover, once the wifi client disconnected, it is better to restart the module mkr1000, otherwise the web page will not be displayed in case of loss of it? I have not found the reason yet.

The motion ranges of the motors can be changed in the Inputs Range of the HTML code.

All of these 2 codes can be used in larger projects using the same technologies.

Code

Master Code (MKR1000)Arduino
Webserver Code for the MKR1000
/*
  WiFi Web Server Contrôle de robot meArm, affichage LCD et led

  created 18 Mars 2018
  par Fabrice bonne
  
 */

#include <SPI.h>
#include <WiFi101.h>
#include <Wire.h>
// size of buffer used to capture HTTP requests
#define REQ_BUF_SZ   90
// size of buffer that stores the incoming string
#define TXT_BUF_SZ   50

char ssid[] = "****";        // your network SSID (name)
char HTTP_req[REQ_BUF_SZ] = {0}; // buffered HTTP request stored as null terminated string
char req_index = 0;              // index into HTTP_req buffer
char txt_buf[TXT_BUF_SZ] = {0};  // buffer to save text to

int led =  LED_BUILTIN;
int status = WL_IDLE_STATUS;
WiFiServer server(80);

void setup() {
  //Initialize serial and wait for port to open:
  Wire.begin(); // Rejoindre le bus I2C (Pas besoin d adresse pour le maitre)
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.println("Access Point Web Server");

  pinMode(led, OUTPUT);      // set the LED pin mode
  digitalWrite(led, LOW);
  // print the network name (SSID);
  Serial.print("Creating access point named: ");
  Serial.println(ssid);

  // Create open network. Change this line if you want to create an WEP network:
  status = WiFi.beginAP(ssid);
  if (status != WL_AP_LISTENING) {
    Serial.println("Creating access point failed");
    // don't continue
    while (true);
  }

  // wait 10 seconds for connection:
  delay(10000);

  // start the web server on port 80
  server.begin();

  // you're connected now, so print out the status
  printWiFiStatus();
}


void loop() {
  // compare the previous status to the current status
  if (status != WiFi.status()) {
    // it has changed update the variable
    status = WiFi.status();

    if (status == WL_AP_CONNECTED) {
      byte remoteMac[6];

      // a device has connected to the AP
      Serial.print("Device connected to AP, MAC address: ");
      WiFi.APClientMacAddress(remoteMac);
      Serial.print(remoteMac[5], HEX);
      Serial.print(":");
      Serial.print(remoteMac[4], HEX);
      Serial.print(":");
      Serial.print(remoteMac[3], HEX);
      Serial.print(":");
      Serial.print(remoteMac[2], HEX);
      Serial.print(":");
      Serial.print(remoteMac[1], HEX);
      Serial.print(":");
      Serial.println(remoteMac[0], HEX);
      digitalWrite(led, HIGH);
    } else {
      // a device has disconnected from the AP, and we are back in listening mode
      Serial.println("Device disconnected from AP");
      digitalWrite(led, LOW);
    }
  }
  
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
      boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                // limit the size of the stored received HTTP request
                // buffer first part of HTTP request in HTTP_req array (string)
                // leave last element in array as 0 to null terminate string (REQ_BUF_SZ - 1)
                if (req_index < (REQ_BUF_SZ - 1)) {
                    HTTP_req[req_index] = c;          // save HTTP request character
                    req_index++;
                }
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    client.println("HTTP/1.1 200 OK");
                    // remainder of header follows below, depending on if
                    // web page or XML page is requested
                    // Ajax request - send XML file
                    if (StrContains(HTTP_req, "ajax_inputs")) {
                        // send rest of HTTP header
                        client.println("Content-Type: text/xml");
                        client.println("Connection: keep-alive");
                        client.println();

                        // print the received text to the Serial Monitor window
                        // if received with the incoming HTTP GET string
                        if (GetText(txt_buf, TXT_BUF_SZ)) {
                          Serial.println("\r\nReceived Text:");
                          Serial.println(txt_buf);
                          Wire.beginTransmission(4);
                          Wire.write(txt_buf);
                          Wire.endTransmission();
                        }
                    }
                    else {  // web page request
                        // send rest of HTTP header
                        client.println("Content-Type: text/html");
                        client.println("Connection: keep-alive");
                        client.println();
                        // send web page
                        client.println("<!DOCTYPE html>");
                        client.println("<head>");
                        client.println("<title>Control meArm</title>");
                        client.println("<meta name='viewport' content='width=device-width, initial-scale=1.0'>");
                        client.println("<script type='text/javascript'>");
                        
                        //--fonctions javascript
                        //fonction texte
                        client.println("function SendText(){");
                        client.println("nocache = \"&nocache=\" + Math.random() * 1000000;");
                        client.println("var request = new XMLHttpRequest();");
                        client.println("strText = \"&txt=\" + document.getElementById('txt_form').form_text.value + \"&end=end\";");
                        client.println("request.open(\"GET\", \"ajax_inputs\" + strText + nocache, true);");
                        client.println("request.send(null);");
                        client.println("}");

                        //fonction verticale
                        client.println("function Verticale(){");
                        client.println("nocache = \"&nocache=\" + Math.random() * 1000000;");
                        client.println("var request = new XMLHttpRequest();");
                        client.println("strText = \"&txt=\" + \"Vertical=\" + document.getElementById('pos_v').posiv_range.value + \"&end=end\";");
                        client.println("positiv = document.getElementById('pos_v').posiv_range.value;");
                        client.println("document.getElementById('reportv').value=positiv;");
                        client.println("request.open(\"GET\", \"ajax_inputs\" + strText + nocache, true);");
                        client.println("request.send(null);");
                        client.println("}");
                       
                        //fonction horizontale
                        client.println("function Horizontale(){");
                        client.println("nocache = \"&nocache=\" + Math.random() * 1000000;");
                        client.println("var request = new XMLHttpRequest();");
                        client.println("strText = \"&txt=\" + \"Horizontal=\" + document.getElementById('pos_h').posih_range.value + \"&end=end\";");
                        client.println("positih = document.getElementById('pos_h').posih_range.value;");
                        client.println("document.getElementById('reporth').value=positih;");
                        client.println("request.open(\"GET\", \"ajax_inputs\" + strText + nocache, true);");
                        client.println("request.send(null);");
                        client.println("}");
                        
                        //fonction angulaire
                        client.println("function Angulaire(){");
                        client.println("nocache = \"&nocache=\" + Math.random() * 1000000;");
                        client.println("var request = new XMLHttpRequest();");
                        client.println("strText = \"&txt=\" + \"Angle=\" + document.getElementById('pos_a').posia_range.value + \"&end=end\";");
                        client.println("positia = document.getElementById('pos_a').posia_range.value;");
                        client.println("document.getElementById('reporta').value=positia;");
                        client.println("request.open(\"GET\", \"ajax_inputs\" + strText + nocache, true);");
                        client.println("request.send(null);");
                        client.println("}");
                        
                        //fonction pince
                        client.println("function Pince(){");
                        client.println("nocache = \"&nocache=\" + Math.random() * 1000000;");
                        client.println("var request = new XMLHttpRequest();");
                        client.println("strText = \"&txt=\" + \"Ouverture=\" + document.getElementById('pos_p').posip_range.value + \"&end=end\";");
                        client.println("positip = document.getElementById('pos_p').posip_range.value;");
                        client.println("document.getElementById('reportp').value=positip;");
                        client.println("request.open(\"GET\", \"ajax_inputs\" + strText + nocache, true);");
                        client.println("request.send(null);");
                        client.println("}");
                        client.println("</script>");
                        client.println("</head>");
                        client.println("<div>");

                        //--Input texte et Input Range
                        //Envoi de texte
                        client.println("<form id='txt_form' name='frmText'>");
                        client.println("<center><textarea name='form_text' rows='2' cols='16'></textarea></center>");
                        client.println("</form>");
                        client.println("<center><input type=submit value='Send Text' onclick=SendText() /></center></div>");
                        client.println("<div>");
                        client.println("<center>Bouger le robot</center><BR><BR>");
                        
                        //Verticalement
                        client.println("<form id='pos_v' name='posText'>");
                        client.println("<center>Verticalement</center><BR>");
                        client.println("<center>Bas<input type=range name='posiv_range' min='20' max='90' value='45' step='1' onchange=Verticale() />Haut</center>");
                        client.println("</form>");
                        client.println("<center><input type=text id='reportv' size='3'/></center><BR>");
                        
                        //Horizontalement
                        client.println("<form id='pos_h' name='posText'>");
                        client.println("<center>Horizontalement</center><BR>");
                        client.println("<center>Proche<input type=range name='posih_range' min='0' max='80' value='45' step='1' onchange=Horizontale() />Loin</center>");
                        client.println("</form>");
                        client.println("<center><input type=text id='reporth' size='3'/></center><BR>");
                        
                        //Angulaire
                        client.println("<form id='pos_a' name='posText'>");
                        client.println("<center>Tourner le robot</center><BR>");
                        client.println("<center>Gauche<input type=range name='posia_range' min='0' max='180' value='90' step='1' onchange=Angulaire() />Droite</center>");
                        client.println("</form>");
                        client.println("<center><input type=text id='reporta' size='3'/></center><BR>");
                        
                        //Pince
                        client.println("<form id='pos_p' name='posText'>");
                        client.println("<center>Pince</center><BR>");
                        client.println("<center>Ouvert<input type=range name='posip_range' min='0' max='90' value='45' step='1' onchange=Pince() />Fermee</center>");
                        client.println("</form>");
                        client.println("<center><input type=text id='reportp' size='3'/></center><BR>");
                        
                        client.println("</div>");
                        client.println("</body>");
                        client.println("</html>");
                       }
                    // reset buffer index and all buffer elements to 0
                    req_index = 0;
                    StrClear(HTTP_req, REQ_BUF_SZ);
                    break;
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
    } // end if (client)
}

// extract text from the incoming HTTP GET data string
// returns true only if text was received
// the string must start with "&txt=" and end with "&end"
// if the string is too long for the HTTP_req buffer and
// "&end" is cut off, then the function returns false
boolean GetText(char *txt, int len)
{
  boolean got_text = false;    // text received flag
  char *str_begin;             // pointer to start of text
  char *str_end;               // pointer to end of text
  int str_len = 0;
  int txt_index = 0;
  
  // get pointer to the beginning of the text
  str_begin = strstr(HTTP_req, "&txt=");
  if (str_begin != NULL) {
    str_begin = strstr(str_begin, "=");  // skip to the =
    str_begin += 1;                      // skip over the =
    str_end = strstr(str_begin, "&end");
    if (str_end != NULL) {
      str_end[0] = 0;  // terminate the string
      str_len = strlen(str_begin);

      // copy the string to the txt buffer and replace %20 with space ' '
      for (int i = 0; i < str_len; i++) {
        if (str_begin[i] != '%') {
          if (str_begin[i] == 0) {
            // end of string
            break;
          }
          else {
            txt[txt_index++] = str_begin[i];
            if (txt_index >= (len - 1)) {
              // keep the output string within bounds
              break;
            }
          }
        }
        else {
          // replace %20 with a space
          if ((str_begin[i + 1] == '2') && (str_begin[i + 2] == '0')) {
            txt[txt_index++] = ' ';
            i += 2;
            if (txt_index >= (len - 1)) {
              // keep the output string within bounds
              break;
            }
          }
        }
      }
      // terminate the string
      txt[txt_index] = 0;
      got_text = true;
    }
  }

  return got_text;
}

// sets every element of str to 0 (clears array)
void StrClear(char *str, char length)
{
    for (int i = 0; i < length; i++) {
        str[i] = 0;
    }
}

// searches for the string sfind in the string str
// returns 1 if string found
// returns 0 if string not found
char StrContains(char *str, char *sfind)
{
    char found = 0;
    char index = 0;
    char len;

    len = strlen(str);
    
    if (strlen(sfind) > len) {
        return 0;
    }
    while (index < len) {
        if (str[index] == sfind[found]) {
            found++;
            if (strlen(sfind) == found) {
                return 1;
            }
        }
        else {
            found = 0;
        }
        index++;
    }

    return 0;
}



void printWiFiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);

}
Slave Code (Arduino UNO)Arduino
The code for the slave card, Arduino UNO. It is used to read the I2C transmission, and convert the orders into movements and LCD display
/*
  WiFi Web Server Contrôle de moteur, affichage LCD et led (Slave)

  created 18 Mars 2018
  par Fabrice bonne
  
 */

#include <Servo.h>
#include <LiquidCrystal.h>
#include <Wire.h> // Librairie pour la communication I2C


LiquidCrystal lcd(7,6,5,4,3,2);          //lcd en bornes 2 à 7
Servo MVertical;
Servo MHorizontal;
Servo MAngle;
Servo MPince;

void setup() {
Wire.begin(4); // Rejoindre le bus à l'adresse #4
Wire.onReceive(receiveEvent); // Preparer une fonction spécifique a la reception de donnee
Serial.begin(9600);
lcd.begin(16, 2);                 //démarrage du module LCD
lcd.clear();
lcd.setCursor(0,0);

MVertical.attach(10);
MHorizontal.attach(8);
MAngle.attach(9);
MPince.attach(11);

MVertical.write(45);
MHorizontal.write(45);
MAngle.write(90);
MPince.write(45);

lcd.clear();
lcd.setCursor(0,0);
lcd.print("EN ATTENTE");
lcd.setCursor(0,1);
lcd.print("D'ENVOI");
}

void loop()
{
  delay(500);
}

// Fonction qui s execute si quelque chose est present sur l interface
void receiveEvent(int howMany)
{
String data = "";
String aff1 = "";
String aff2 = "";
String recherche = "";
int dl;
bool Mot = false;

while (Wire.available()) {     //lecture des ordres envoyés
    data += (char)Wire.read();
}
    Serial.println(data);
    recherche = "Vertical=";  //Recherche des ordres moteurs
    if (data.indexOf(recherche)!=-1){
      aff1 = "Vertical=";
      aff2 = data.substring(9,12);
      Serial.print("Nouvelle valeur V=");
      Serial.println(aff2);
      MVertical.write(aff2.toInt());
      Mot = true ;
    }
    recherche = "Horizontal=";
    if (data.indexOf(recherche)!=-1){
      aff1 = "Horizontal=";
      aff2 = data.substring(11,14);
      Serial.print("Nouvelle valeur H=");
      Serial.println(aff2);
      MHorizontal.write(aff2.toInt());
      Mot = true ;
    }
    recherche = "Angle=";
    if (data.indexOf(recherche)!=-1){
      aff1 = "Angle=";
      aff2 = data.substring(6,9);
      Serial.print("Nouvelle valeur A=");
      Serial.println(aff2);
      MAngle.write(aff2.toInt());
      Mot = true ;
    }
    recherche = "Ouverture=";
    if (data.indexOf(recherche)!=-1){
      aff1 = "Ouverture=";
      aff2 = data.substring(10,13);
      Serial.print("Nouvelle valeur O=");
      Serial.println(aff2);
      MPince.write(aff2.toInt());
      Mot = true ;
    }
    if (Mot == false) {  //Si c'est un texte, découpage et affichage
    dl = data.length();
    Serial.print("longueur :");
    Serial.println(dl);
    if (dl > 16) {
      aff1 = data.substring(0, 16);
      aff2 = data.substring(16, dl);
      Serial.print("découpage :");
      Serial.println(aff1);
      Serial.println(aff2);
     }
    else {
      aff1 = data;
      Serial.println("découpage non requis");
      }
    }
    Serial.println();
    lcd.clear();       //Affichage des infos moteur et texte en Relay
    lcd.setCursor(0,0);
    lcd.print(aff1);
    lcd.setCursor(0,1);
    lcd.print(aff2);
}

Comments

Similar projects you might like

Servo Control with TV Remote Control

Project showcase by eldo85

  • 6,342 views
  • 5 comments
  • 21 respects

MeArm Robot Arm - Your Robot - V1.0

Project tutorial by Benjamin Gray

  • 19,311 views
  • 3 comments
  • 35 respects

Wifi Enabled 2/4 Wheeled Robot Platform Utilizing MKR1000

Project showcase by James Martel

  • 3,310 views
  • 6 comments
  • 11 respects

Smartphone Controlled Arduino 4WD Robot Car

Project in progress by Andriy Baranov

  • 53,239 views
  • 43 comments
  • 98 respects

Control your RoboArm with your Smartphone

Project in progress by Team Zone Team

  • 9,171 views
  • 7 comments
  • 27 respects

PHPoC - Arduino Self Balancing Robot with BT+Web Control

Project in progress by Suyog Gunjal

  • 3,679 views
  • 2 comments
  • 23 respects
Add projectSign up / Login