Hamza Khalid
Published

Robo Hazel using Arduino and WIZnet S2E

Robo Hazel is a robot prototype made using Arduino and WIZnet S2E module to advance industry 4.0 and solve the problem of message delivery.

AdvancedFull instructions provided4 days1,896
Robo Hazel using Arduino and WIZnet S2E

Things used in this project

Hardware components

WIZ750SR-TTL-EVB Kit
WIZnet WIZ750SR-TTL-EVB Kit
×1
Arduino UNO
Arduino UNO
×2
Tablet PC
×1
Tablet stand
×1
USB-A to B Cable
USB-A to B Cable
×1
Micro usb to Otg cable
×1
DC motor (generic)
×2
L298N Motor Drive Controller Board DC Dual H-Bridge
×1
IR Sensor Module
×3
12V - 7A Battery
×1
Breadboard (generic)
Breadboard (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Arduino IDE
Arduino IDE
PyCharm IDE
Adobe Photoshop

Story

Read more

Custom parts and enclosures

Eye opened

Eye closed

Schematics

Robot circuit

WIZ750SR Pinout

Code

Arduino - User Side

C/C++
#include <EEPROM.h>

//Using Arduino's EEPROM to read and write the message. Following are the functions for reading and writing from EEPROM
const int EEPROM_MIN_ADDR = 0;
const int EEPROM_MAX_ADDR = 511;

boolean eeprom_is_addr_ok(int addr) {
      return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
}

boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
      int i;
      if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
      return false;
      }
      for (i = 0; i < numBytes; i++) {
      EEPROM.write(startAddr + i, array[i]);
      }
      return true;
}

boolean eeprom_write_string(int addr, const char* string) {
      int numBytes; 
      numBytes = strlen(string) + 1;
      return eeprom_write_bytes(addr, (const byte*)string, numBytes);
}

boolean eeprom_read_string(int addr, char* buffer, int bufSize) {
      byte ch; 
      int bytesRead;
      if (!eeprom_is_addr_ok(addr)) {
      return false;
      }
      
      if (bufSize == 0) { 
      return false;
      }
      if (bufSize == 1) {
      buffer[0] = 0;
      return true;
      }
      bytesRead = 0; // initialize byte counter
      ch = EEPROM.read(addr + bytesRead); // read next byte from eeprom
      buffer[bytesRead] = ch; // store it into the user buffer
      bytesRead++; 
      while ( (ch != 0x00) && (bytesRead < bufSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
      // if no stop condition is met, read the next byte from eeprom
      ch = EEPROM.read(addr + bytesRead);
      buffer[bytesRead] = ch; // store it into the user buffer
      bytesRead++; // increment byte counter
      }
      
      if ((ch != 0x00) && (bytesRead >= 1)) {
      buffer[bytesRead - 1] = 0;
      }
      return true;
}

const int BUFSIZE = 100;
char buf1[BUFSIZE];
char buf2[BUFSIZE];
String myString; 
char myStringChar[BUFSIZE];

//HTML form
const char webpage[] PROGMEM  = "<!DOCTYPE HTML>"
"<HTML>"
"<H1>Robo Hazel </H1>"
"<FORM ACTION=\"http://192.168.1.104\" method=get > "
"Message: <INPUT TYPE=TEXT NAME=\"Message\" VALUE=\"\" SIZE=\"100\" MAXLENGTH=\"100\"><BR>"
"<INPUT TYPE=SUBMIT NAME=\"_submit\" VALUE=\"Announce\">"
"</FORM>"
"</HTML>";

int k;    // counter variable
char myChar;

void setup() {
  
  Serial.begin(115200);

}

void loop() {
       
  while (!Serial);  // wait for serial port to connect.

         //Reading and displaying the message that was stored in Arduino's EEPROM earlier
         Serial.print("<P>");
         Serial.print("MESSAGE TO BE ANNOUNCED: ");   
         eeprom_read_string(0, buf2, BUFSIZE);
         Serial.print(buf2);
         Serial.print("</P>");

          //Printing the HTML form 
          for (k = 0; k < strlen_P(webpage); k++) 
          {
            myChar =  pgm_read_byte_near(webpage + k);
            Serial.print(myChar);
          }
          Serial.println();
          delay(800);

          //Reading the request
          String request = Serial.readStringUntil('\n');  
          request.replace('+', ' '); //Removing all the plus signs in message
          
          //Parsing message from request
          
          int firstIndex = request.indexOf('Message=');
          int lastIndex = request.indexOf('&_', firstIndex + 1);

          //Saving the parsed message into output variable
          String output=request.substring(firstIndex + 1, lastIndex-1); 
          
          //Checking if the message exists and writing it into Arduino's EEPROM for future use
         
          if(lastIndex-firstIndex>1){ 
              output.toCharArray(myStringChar, BUFSIZE);
              strcpy(buf1, myStringChar);  
              eeprom_write_string(0, buf1);
          }
          
      }
 

Arduino-Robot side

C/C++
int S0 = 2, S1 = 3, S2 = 4; //IR sensors
int S0sensor,S1sensor,S2sensor; //Variable declaration of sensors

int motRight1= 7 ;
int motRight2= 8; 
int motRightpwm= 6 ;
int motLeft1= 12;
int motLeft2= 13 ;
int motLeftpwm= 11;

//Calibrate the PWM values of your motors to adjust speed until the robot goes straight
int rightPWM = 250; //PWM value of right motor
int leftPWM = 68; //PWM value of left motor

//Functions declaration
void motfwd();
void motbwd();
void motright();
void motleft();
void motstop();

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  pinMode(S0, INPUT);
  pinMode(S1, INPUT);
  pinMode(S2, INPUT);
  
  pinMode(motRight1,OUTPUT);
  pinMode(motRight2,OUTPUT);
  pinMode(motRightpwm,OUTPUT);
  pinMode(motLeft1,OUTPUT);
  pinMode(motLeft2,OUTPUT);
  pinMode(motLeftpwm,OUTPUT);
 int count = 0;
}

void loop() {

 /* When the robot is started "Message: Announce" is printed once which gives the signal to
  * the python application to get the message to be spoken from the server and convert the 
  * text into speech.
  */ 
 static bool once = false;
    if (once == false)
{
    once = true;
    Serial.println("Message: Announce"); 
}

  //Reading the values of IR sensors
  S0sensor = digitalRead(2);
  S2sensor = digitalRead(3);
  S1sensor = digitalRead(4); 


  //------------COMMANDS TO FOLLOW A BLACK LINE PATH ------------//
   if ((S0sensor == LOW)&&(S1sensor == HIGH)&&(S2sensor == LOW))
   motfwd();
   else if ((S0sensor == HIGH)&&(S1sensor == LOW)&&(S2sensor == LOW))
   motright();
   else if ((S0sensor == LOW)&&(S1sensor == LOW)&&(S2sensor == HIGH))
   motleft();

  /*When the robot reaches its final position it stops and "Signal: 1 1 1" 
   * is printed which gives a signal to python application to announce
   * speak the text that had been converted to speech earlier.
   */
   else if ((S0sensor == HIGH)&&(S1sensor == HIGH)&&(S2sensor == HIGH))
   {
    motstop();
   Serial.println("Signal: 1 1 1");
   delay(1000*15);
   }
   
}

void motfwd(){
digitalWrite(motRight1,LOW);
digitalWrite(motRight2, HIGH);
analogWrite(motRightpwm, rightPWM);
digitalWrite(motLeft1,HIGH);
digitalWrite(motLeft2, LOW);
analogWrite(motLeftpwm, leftPWM);
  }
void motleft(){
digitalWrite(motRight1,LOW);
digitalWrite(motRight2, HIGH);
analogWrite(motRightpwm, rightPWM);
digitalWrite(motLeft1,HIGH);
digitalWrite(motLeft2, HIGH);
analogWrite(motLeftpwm, leftPWM);
  }
  void motright(){
digitalWrite(motRight1,HIGH);
digitalWrite(motRight2, HIGH);
analogWrite(motRightpwm, rightPWM);
digitalWrite(motLeft1,HIGH);
digitalWrite(motLeft2, LOW);
analogWrite(motLeftpwm, leftPWM);
  }
  void motbwd()
  {
digitalWrite(motRight1,LOW);
digitalWrite(motRight2, HIGH);
analogWrite(motRightpwm, rightPWM);
digitalWrite(motLeft1,HIGH);
digitalWrite(motLeft2, LOW);
analogWrite(motLeftpwm, leftPWM);
  }
   void motstop()
  {
digitalWrite(motRight1,LOW);
digitalWrite(motRight2, LOW);
digitalWrite(motLeft1,LOW);
digitalWrite(motLeft2, LOW);

  }

Python Software for tablet PC

Python
from gtts import gTTS
import pygame
from pygame import mixer
from tempfile import TemporaryFile
import serial
import os
import time
import urllib.parse
import re

#The arduino is connected to COM12 of our tablet PC and the baudrate is 9600
ser = serial.Serial(port='COM12', baudrate=9600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout=10)

pygame.init()

black = (0,0,0)
white = (255,255,255)

gameDisplay = pygame.display.set_mode((0,0),pygame.FULLSCREEN))
pygame.display.set_caption('Robo Hazel')
clock = pygame.time.Clock()
CurrentPath = os.path.dirname(__file__)
eyeFolderPath = os.path.join(CurrentPath, 'images')
m1 = pygame.image.load(os.path.join(eyeFolderPath, 'opened.png'))
m2 = pygame.image.load(os.path.join(eyeFolderPath,"closed.png"))
eyeCurrentImage = 1

def gameloop(eyeCurrentImage):
    gameExit = False

    while not gameExit:
        for event in pygame.event.get():
             if event.type == pygame.QUIT:
                 gameExit = True
        gameDisplay.fill(white)

        #Blinking of eyes
        if (eyeCurrentImage == 1):
            gameDisplay.blit(m1, (200, 200))
            time.sleep(0.5)
        if (eyeCurrentImage == 2):
            gameDisplay.blit(m2, (200, 200))
            time.sleep(3)
        if (eyeCurrentImage == 2):
            eyeCurrentImage = 1
        else:
            eyeCurrentImage += 1

        #Reading messages from the serial port
        if (ser.isOpen()):
            string=ser.readline().decode('ascii')
            print(string)
            if len(string)>0:
                for i in range(0, len(string)):
                    if string[i] == ':':
                        check = string[i - 1]
                        if check == 'e': #Finds this signal --> Message: Announce, from arduino and starts extracting the message from the webpage and converting it to speech
                            try:
                                url = "http://192.168.1.104"
                                values = {'s': 'basics',
                                          'submit': 'search'}
                                data = urllib.parse.urlencode(values)
                                data = data.encode('utf-8')
                                req = urllib.request.Request(url, data)
                                resp = urllib.request.urlopen(req)
                                respData = resp.read()
                                paragraph = re.findall(r'<p>(.*?)</p>', str(respData))
                                for eachP in paragraph:
                                    serial_message = eachP

                            #Exception handling in case of BadStatusLine exception (Extracting the message from the error itself)
                            except Exception as e:
                                output = str(e)
                                for i in range(0, len(output)):
                                    if output[i] == '>':
                                        break
                                initial = i
                                for j in range(i, len(output)):
                                    if output[j] == '<':
                                        break
                                final = j
                                serial_message = output[initial + 26:final]

                            #Converting the text to speech
                            tts = gTTS(text=serial_message, lang='en-us')
                            mixer.init()
                            sf = TemporaryFile()
                            tts.write_to_fp(sf)
                            sf.seek(0)
                            mixer.music.load(sf)
                            pygame.time.Clock().tick(10)
                        if check == 'l': #Finds this signal --> Signal: 1 1 1, from arduino and the text that was converted into speech earlier is spoken
                            mixer.music.play()
                            while pygame.mixer.music.get_busy():
                                print("Playing")
                                pygame.time.Clock().tick(10)

        pygame.display.flip()
        clock.tick(120)

gameloop(eyeCurrentImage)
pygame.quit()
quit()

Credits

Hamza Khalid

Hamza Khalid

2 projects • 9 followers

Comments