I am using an Arduino Uno as my micro controller to control the motors and servos which will be on the robot. I found ways to control the uno over the internet, however, they either require the purchase of a breakout board or USB connection to another computer. I own a couple Raspberry Pis and figured I could use what I had already to do the job. While (I think) it is totally possible to use just Arduino code to do all of this and use the RPi as the communication device, I found it more convenient given my level of understanding to simply use the RPi GPIO pins as switches for input to the Uno to trigger motor and servo control. Essentially the device will work as follows:
Since I am still (patiently) waiting for my parts. I will test my web based control using a single servo.
Raspberry GPIO control over the web
A man by the name of Eric wrote up this wonderful framework called WebIOPi, which allows for web-based GPIO control using a python-based server. The installation and usage of this framework is very simple and can be found on his site. The best part of this framework is the ability to customize the UI using the WebIOPi API.
I thought it would be rather neat to control the device using keyboard input. That is, the left arrow and right arrows will control the motion of the servo. I mapped each keyboard input to it's own RPi GPIO pin, so while the key is pressed the pin is high, and when released the pin is low. This was simple using some jQuery functions along with the WebIOPi API.
Web controlled robot from RPi and Uno |
Since I am still (patiently) waiting for my parts. I will test my web based control using a single servo.
Raspberry GPIO control over the web
A man by the name of Eric wrote up this wonderful framework called WebIOPi, which allows for web-based GPIO control using a python-based server. The installation and usage of this framework is very simple and can be found on his site. The best part of this framework is the ability to customize the UI using the WebIOPi API.
WebIOPi Interface |
//Use webiopi object to initialize pins webiopi().read(function(){ //Init GPIO Pins 17 and 22 webiopi().setFunction(17,"OUT"); webiopi().setFunction(22,"OUT"); }); //Using the up(37) and down(39) arrows on pin 17,22. //If key is pressed, pin goes high $(window).keydown(function(event){ if(event.keyCode == 37) setValue(17,1); if(event.keyCode == 39) setValue(22,1); }); //If key is released, pin goes low $(window).keyup(function(event){ if(event.keyCode == 37) setValueK(17,0); if(event.keyCode == 39) setValueK(22,0); }); //Use REST API to set pin value function setValueK(gpio, value){ $.post('/GPIO/' + gpio + "/value/" + value, function(data){ updateValue(gpio,value); }); } //Return data function updateValueK(gpio, value){ var style = (value == 1) ? "HIGH" : "LOW"; $("#gpio"+gpio).attr("class",style); }Interface circuit for RPi and Arduino
I decided to keep the RPi and Arduino circuits isolated as I feel this would be the safest approach to combining them. This means that they each have their own power sources, which may mean the robot has a little more weight and costs a bit more, however, it means I won't have to figure out how to run it all off of one power source without frying everything. I used an opto-isolator (4n35) as a switch to provide the input for the Arduino. Using the following circuit, when the RPi pin goes high, the Arduino pin will go low. This can be detected in the Arduino code to control the servo.
Circuit diagram (apologies for the lack of standards I am no electrical engineer) |
The Arduino sketch here is rather simple. If it detects pin 2 or 4 go low, then it will start to rotate the servo (which in this case is on pin 5). Pin 2 will rotate the servo in one direction, Pin 4 will rotate the sevro in the opposite direction.
#include <servo.h> //Servo controller Servo servoMain; //Servo Definitions int servoPin = 5; int minP = 750; int maxP = 2250; int stepS = 3; int delayTime = 20; //Pin 2 definitions int up = 2; int valUp; int bsUp; //Pin 4 definitions int down = 4; int valDown; int bsDown; //Keep track of servo deg int deg = 0; void setup(){ //Init Pins pinMode(up, INPUT); pinMode(down, INPUT); //Get inital reading bsUp = digitalRead(up); bsDown = digitalRead(down); //Init servo servoMain.attach(servoPin,minP,maxP); } //Loop void loop(){ //Read pins valUp = digitalRead(up); valDown = digitalRead(down); //Only act if changed (reduce calculations) if ( (valUp != bsUp) || (valDown != bsDown) ){ //If pin 2 is low, add the step to the servo if ( valUp == 0 ){ deg += stepS; //Don't go past 180 if( deg >= 180){ deg = 180; } servoMain.write(deg); delay(delayTime); } //If pin 4 is low, subtract the step from the servo if ( valDown == 0 ){ deg -= stepS; //Don't go past 0 if( deg <= 0){ deg = 0; } servoMain.write(deg); delay(delayTime); } } }
Example:
In this example I also added two buttons to the page for testing.
This comment has been removed by the author.
ReplyDeleteExcellent tutorial. I only have a question: where did you write the jScript code above? in what file? Thank you.
ReplyDeleteIn the html file. Check out the WebIO demo to see their format. I basically just adjusted what they had.
DeleteDid you do any modification to the py file? Whatever I do, it does not seem to work.
Deletecan you please upload your code from your finished html file. I am trying to rewrite the light switch tutorials html file and insert your but its just showing a blank page without any gpio activity.
ReplyDelete