Control MeArm Robot With MKR1000 And Your Smartphone




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

dsc01047_vNtwBzRndc

Things used in this project

Story

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.

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] = {}; // buffered HTTP request stored as null terminated string
char req_index = ;              // index into HTTP_req buffer
char txt_buf[TXT_BUF_SZ] = {};  // 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[], 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 = ;
                    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 = ;
  int txt_index = ;
  
  // 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[] = ;  // terminate the string
      str_len = strlen(str_begin);

      // copy the string to the txt buffer and replace %20 with space ' '
      for (int i = ; i < str_len; i++) {
        if (str_begin[i] != '%') {
          if (str_begin[i] == ) {
            // 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] = ;
      got_text = true;
    }
  }

  return got_text;
}

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

// 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 = ;
    char index = ;
    char len;

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

    return ;
}



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);

}
READ  Writing a python module to simulate a LCD

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(,);

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(,);
lcd.print("EN ATTENTE");
lcd.setCursor(,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(, 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(,);
    lcd.print(aff1);
    lcd.setCursor(,1);
    lcd.print(aff2);
}
READ  Hercules: The Motion Controlled Android Robot using Arduino

Source : Control MeArm Robot With MKR1000 And Your Smartphone




Leave a Comment

*
= 4 + 7

(Spamcheck Enabled)

Read previous post:
A Guide to Metal Core PCBs by PCBGOGO

Introduction: The use of LED based electronics has significantly increased in the past few years. They have proven to be...

Close
Scroll to top