Project tutorial

Pick to Light Project 2 WiFi © LGPL

In the second project in my pick to light, I am using WIFI to pass the data between PC and Arduino.

  • 1,474 views
  • 14 comments
  • 5 respects

Components and supplies

About this project

This is the second project in my pick to light exploration. In the first, I outlined how I see a simple pick to light working and I created a simple pick to light using serial communication (Please read this if you wish to understand more of what I am doing here).

It worked but was tethered to the PC by the cable. In this project I want to develop the process using Wi-Fi and additionally I want to include the sequence number in the picking confirmation so that if anything goes wrong the system knows where the worker has picked up to. I am going to use an MKR1000 in the same way as I did in project 1 but communicate using WiFi. To do this I am going to use UDP (User Datagram Protocol ). Though I have never used this before, thanks to the libraries in Arduino and Python, this proved relatively easy to create.

The following steps are broadly similar to project 1 so if you have followed that then you will be already familiar with some of the steps and they won't need to be repeated.

Step 1

To get started we need to have Python v 3.6 or greater on our laptop or pc. You can download that from here:

https://www.python.org/downloads/

Step 2

This time we will use the Python socket library for communicating and it is already installed so nothing needs doing to make UDP work.

Step 3

We also need the Arduino IDE either the PC version or the Web version. These can be downloaded here:

https://www.arduino.cc/en/Main/Software

or connected to here:

https://create.arduino.cc/

The instructions on the site are comprehensive so I won't duplicate them unnecessarily.

Step 4

Launch the Python IDLE on your PC or Laptop and type: import os press: enter.

Then type: os.getcwd() this should give you your current working directory (cwd).

Python working directory

Step 5

In Notepad I created a comma separated value file and it quite simply contains a sequence number formatted to always be 4 digits and a bin number separated by a comma. See Notepad screen shot below and also text file attached which you can download. I saved this as sequence1.txt in the cwd that we gathered in step 4 (you can save the file with the extension of csv but it isn't necessary for the csv to work). Saving the file to the cwd simplifies things when we come to read in the file with the python script as we won't have to specify a location where the file is stored because it will automatically look in the cwd.

txt file containing csv sequence

Step 6

We will use serial in the Arduino sketch but only so we can see the printed messages on the serial monitor.

Step 7

The Python script needs to read in the content of the csv file one line at a time and send the sequence number and the Bin number across the UDP connection and then wait until the Arduino returns acknowledgement, which is the sequence number of the last bin number, to say that the part is picked. If the sequence number received does not match the last sequence number sent, the Python program will stop with an error message indicating the sequence number. This will enable the sequence to be restarted at the correct place. I have added comments to the script so you can understand what I have written.

Copy the script and then launch the IDLE and then >File >New File and paste the script into the window. Then >File >Save As give it a name (it doesn't matter what you call it as long as you know the name).

Step 8

The Arduino sketch needs to connect to the internet then wait to receive the udp data from the PC for the next pick. It then acts on what it receives by lighting the LED that matches the bin in the sequence. It then needs to monitor the button that represents that bin to see if it is pressed. Once the worker presses the button to say the part is picked the sketch turns out the LED and sends a message containing the last sequence number back to the PC or Laptop to say the part was picked. It then then waits to receive the details for the next pick.

So if you are using the Arduino web editor copy from below the sketch and in the Arduino Web Editor select >sketchbook >NEW SKETCH

Arduino Web Editor

Then paste the script in the new sketch completely replacing everything that is in there.

If you are using the Arduino web editor as soon as you paste in the sketch the editor identifies the need to create a secret file which will contain the SSID and password for that server.

It is just a simple case of adding the relevant details to the file in the spaces provided.

With Arduino IDE it may be just as easy but if it is I couldn't find it. However, because I started my sketch with the example sketch WiFiUdpSendReceiveString.

If you open this you will find a tab arduino_secrets.h already inside it. Add your SSID and password then paste the sketch below over the sketch already there and save as any name you like.

If you are using the Arduino IDE you will need to include the library WiFi101 the following link explains how to add a library if you don't know.

https://www.arduino.cc/en/Guide/Libraries

Download to the MKR1000.

Step 9

Connect everything up as per the fritzing diagram. If you have followed project 1 then you will see that I have wired this differently. The reason behind this is that as soon as the WiFi on the MKR1000 becomes active for some reason the power drops across pins 8 and 9 and the LEDs won't illuminate. I couldn't find anyone else on the web posting anything about this problem so I used the transistor to get round it. I'm sure there will be an explanation for this but so far I haven't found it.

Warning! Please make sure that the resistors you use are suitable for the LED and the NPN transistor you use. Also be certain that you wire this up correctly as allowing the 5V to short across the pins 8 and 9 could destroy your Arduino. Use a diode if you are unsure.

Step 10

Check the Arduino has connected to the server and then run the Python script using F5 and the LED that represents Bin1 will light up. Pressing the button to confirm the part has been picked will send the sequence number back to the Python program where it will be checked and if correct, the next sequence is sent.

The Python output will look like this

The serial monitor output will look like this:

You can test the sequence failure by commenting the line:

myseq.toCharArray(ReplyBuffer, 5);

and uncommenting the line:

//char ReplyBuffer[5] = "0001";

as follows;

When you run the python program now the execution will stop after the second bin as it will report the sequence number of the first bin.

In the event of a sequence failure the person creating the sequence would need to edit the file containing the sequence and restart the arduino and the Python program.

Conclusion

Well I think I have achieved what I set out to do. It is simple and would be easy to scale up to a full size working version. However, I can already see that a project 3 could make improvements and even though the competition will have finished, before I get chance to do a further project, I think I would like to do this to see how I can make it better but still keeping the initial idea of simplicity.

Code

Arduino sketchArduino
The sketch to be loaded to the MKR1000
#include <SPI.h>
#include <WiFi101.h>
#include <WiFiUdp.h>

const int OKbutton = 2; // set the pin for the okay button/switch
const int Bin1 = 8; // the pin that the LED for bin 1 is attached to
const int Bin2 = 9; // the pin that the LED for bin 2 is attached to
String mydata = " ";  // a variable to read incoming serial data into set to empty string
String myseq = " ";
int buttonPress = 0; // a variable to store state of the button/switch

int status = WL_IDLE_STATUS;
#include "arduino_secrets.h" 
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0;            // your network key Index number (needed only for WEP)

unsigned int localPort = 2390;      // local port to listen on

char packetBuffer[255]; //buffer to hold incoming packet
char  ReplyBuffer[5] = "   ";       // a string to send back
String mystring;
WiFiUDP Udp;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);// all serial statements are not needed once set up
//while (!Serial) {
// wait for serial port to connect. Needed for native USB port only
}

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to WiFi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to wifi");
  printWiFiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  Udp.begin(localPort);

}

void loop() {

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize)
  {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) packetBuffer[len] = 0;
    Serial.println("Contents:");
    Serial.println(packetBuffer);
    String mystring(packetBuffer);
    mydata = mystring.substring(4);
    myseq = mystring.substring(0,4);
    Serial.println(mydata);
    Serial.println(myseq);
    
       while (mydata != " "){ //Test to see if mydata is still empty if it isn't check which bin should be lit up
      if (mydata == "Bin1"){ // start bin 1 routine
        digitalWrite(Bin1, HIGH); // light LED for bin 1 by setting pin high
        digitalWrite(Bin2, LOW);  // set LED for bin 2 off by setting pin low
            while (buttonPress != HIGH) { // wait for button press loop
              buttonPress = digitalRead(OKbutton); //keep checking button
              mydata = " "; //set mydata back to empty string
    }
        digitalWrite(Bin1, LOW);// turn led for bin 1 off
        Serial.println("Picked"); //send message to PC
        buttonPress = 0; //reset button low
        delay(1000);
      }
      if (mydata == "Bin2"){// start bin 2 routine
        digitalWrite(Bin2, HIGH);// light LED for bin 2 by setting pin high
        digitalWrite(Bin1, LOW); // set LED for bin 1 off by setting pin low
            while (buttonPress != HIGH) { // wait for button press loop
              buttonPress = digitalRead(OKbutton); //keep checking button
              mydata = " "; //set mydata back to emty string
    }
        digitalWrite(Bin2, LOW); // turn led for bin 1 off
        Serial.println("Picked"); //send message to PC
        buttonPress = 0; //reset button low
        delay(1000);
      }
 
    }

    // send a reply, to the IP address and port that sent us the packet we received
    myseq.toCharArray(ReplyBuffer, 5);
    //char ReplyBuffer[5] = "0001"; // for testing only
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
    Serial.println(ReplyBuffer);
  }
}


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");
}
Python ScriptPython
Python Script to be run.
## load the necessary libraries
import csv
import socket
import time
import sys

UDP_IP = "192.168.1.119" ## the ip of our Arduino
UDP_PORT = 2390 ## the port we wish to communicate on

print("UDP target IP:", UDP_IP) ## display ip to user
print("UDP target port:", UDP_PORT) ## display port to user

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # create a socket


time.sleep(5)
##open csv file and read it in one line at a time
with open('sequence1.txt') as csvDataFile: 
    csvReader = csv.reader(csvDataFile)
    for row in csvReader: ##for each line do the following
        myseq = row[0] ##read in the sequence number
        mystate = row[1] ##read in the bin number
        myrow = row[0] + row[1]
        print("Current sequence being picked ",myseq,"from ", mystate)
        sock.sendto(bytes(myrow, "utf-8"), (UDP_IP, UDP_PORT)) # send seq and bin number
        data = "" # set data to blank to enter while loop i=until data is received
        while data == "": # until data is received keep looping through
            (data, addr) = sock.recvfrom(1024) # set data to data received from socket
            mytest = data.decode( "utf-8") #set mytest to equal value received over socket
            print ("picked = ", mytest) # print the value received
            if mytest != myseq: # test what has ben received matches what was expected i.e. last seq sent
                print ("there is a sequence fault at sequence", mytest) # display message to indicate a fault
                sys.exit() #end program execution if fault exists
SequencePlain text
Sequence file for the python program
0001,Bin1
0002,Bin2
0003,Bin1
0004,Bin2
0005,Bin1
0006,Bin2
0007,Bin1
0008,Bin2
0009,Bin1
0010,Bin2
0011,Bin1
0012,Bin2
0013,Bin1

Schematics

Pick to light UDP Project 2
Connections for the UDP Pick to Light
picktolightudp_OCbpNt9XPK.fzz

Comments

Similar projects you might like

Pick to Light Project 1 Serial

Project tutorial by PAJ

  • 1,228 views
  • 0 comments
  • 4 respects

Control Your Light Switch with Your Smartphone

Project tutorial by Alasdair Allan

  • 16,362 views
  • 1 comment
  • 34 respects

Control Arduino Uno Using ESP8266 WiFi Module and Blynk App

Project tutorial by Adithya TG

  • 35,857 views
  • 13 comments
  • 40 respects

Arduino Simple "Camera Slider" Electronics

Project tutorial by Ian Cumming

  • 8,102 views
  • 3 comments
  • 19 respects

ArduMeter - Arduino Incident Light Meter

Project tutorial by Alan Wang

  • 6,282 views
  • 2 comments
  • 19 respects

The Light Box

Project tutorial by Wpeeters

  • 4,688 views
  • 2 comments
  • 21 respects
Add projectSign up / Login