




Thanks very much for this - not had a chance to look in depth as I have been trying to get my head around solutions such as node.js / socket.io and tornado / python.danjperron wrote:The arduino nano have the usb port on it . Simply connect the usb directly into the pi et use standard serial communication to control it.
But I will ditch the arduino since you don't need it.
I do have something similar with what you have and it is running on Pi A version.
I'm using webiopi which is a python web server that you could pass python function into it.
This is a post explaining the webinterface. (It's in french but the pyhon and web page are easy to figure out).
viewtopic.php?p=353089#p353089


danjperron;danjperron wrote:There was another post about moving a robot using the web.
viewtopic.php?p=784173#p784173
I post detail method on how to implement webiopi with a simple html form.
I use websocket with my RF24 arduino sensor on battery with the help of MQTT to read all my IOT sensors.
The webpage use web socket to get the sensor information. So websocket is good way to communicate.
B.T.W. webiopi is a python webserver. You are able to create your own python function and implement a javascript handshake with them. This is quite nice . I do have some webiopi chitchat to read or set I/O this way.
I don't see why not! python have code for serial and socket connection.do you believe that I would be able to use webiopi with python websockets and a serial interface to an Arduino?
Code: Select all
#!/usr/bin/env python
from time import sleep
import webiopi
import RPi.GPIO as GPIO
from select import select
import serial
import ossaudiodev
import wave
from threading import Thread
out = serial.Serial('/dev/ttyAMA0',38400)
CamX = int(3000)
CamY = int(3000)
#set io pin
EnA = 11
EnB = 15
Out1 = 24
Out2 = 21
Out3 = 19
Out4 = 23
GPIO.setmode(GPIO.BOARD)
def Forward():
GPIO.output(Out1,True)
GPIO.output(Out3,True)
GPIO.output(Out2,False)
GPIO.output(Out4,False)
GPIO.output(EnA,True)
GPIO.output(EnB,True)
def Stop():
GPIO.output(Out1,False)
GPIO.output(Out3,False)
GPIO.output(Out2,False)
GPIO.output(Out4,False)
GPIO.output(EnA,True)
GPIO.output(EnB,True)
def Standby():
GPIO.output(Out1,False)
GPIO.output(Out3,False)
GPIO.output(Out2,False)
GPIO.output(Out4,False)
GPIO.output(EnA,False)
GPIO.output(EnB,False)
def Reverse():
GPIO.output(Out2,True)
GPIO.output(Out4,True)
GPIO.output(Out1,False)
GPIO.output(Out3,False)
GPIO.output(EnA,True)
GPIO.output(EnB,True)
def TurnRight():
GPIO.output(Out1,True)
GPIO.output(Out3,False)
GPIO.output(Out2,False)
GPIO.output(Out4,True)
GPIO.output(EnA,True)
GPIO.output(EnB,True)
def TurnLeft():
GPIO.output(Out1,False)
GPIO.output(Out3,True)
GPIO.output(Out2,True)
GPIO.output(Out4,False)
GPIO.output(EnA,True)
GPIO.output(EnB,True)
def ServoSpeed(id , speed):
out.write('\x80\x01\x01' + chr(id) + chr(speed))
print("Servo ",id,"speed = ",id,speed)
def ServoSleep(id):
out.write('\x80\x01\x00' + chr(id) + chr(15))
print("Servo ",id," to sleep")
def Servo( id , ServoPosition):
out.write('\x80\x01\x04' + chr(id) + chr(ServoPosition >>7) + chr(ServoPosition & 0x7f))
print("Servo ",id," = ",ServoPosition)
def CloseJaw():
Servo(2,4400)
def OpenJaw():
Servo(2,1000)
def play(filename):
print "opening file"
sound_file = wave.open(filename,'rb')
print "getting parameters"
(nc, sw, fr, nf, comptype, compname) = sound_file.getparams()
print "parameters were", (nc, sw, fr, nf, comptype, compname)
print "opening audio"
sound = ossaudiodev.open('w')
print "setting parameters"
sound.setparameters(ossaudiodev.AFMT_S16_NE, nc, fr)
print "readframes"
data = sound_file.readframes(nf)
print "closing file"
sound_file.close()
print "writing data"
sound.write(data)
# Never gets here, freezes on the previous line.
print "closing sound device"
sound.close()
def Play1():
thread = Thread(target = play, args=("ialert.wav",))
thread.start()
def Play2():
thread = Thread(target = play, args=("tos-redalert.wav",))
thread.start()
def Play3():
thread = Thread(target = play, args=("s3.wav",))
thread.start()
def Play4():
thread = Thread(target = play, args=("s4.wav",))
thread.start()
def Play5():
thread = Thread(target = play, args=("s5.wav",))
thread.start()
def Play6():
thread = Thread(target = play, args=("s6.wav",))
thread.start()
def Play7():
thread = Thread(target = play, args=("s7.wav",))
thread.start()
def Play8():
thread = Thread(target = play, args=("s8.wav",))
thread.start()
def Play9():
thread = Thread(target = play , args=("s9.wav",))
thread.start()
#============ MAIN ==============
homeX = 2800
homeY = 3000
CamX = homeX
CamY = homeY
def CameraSet():
global CamX
global CamY
Servo(0, CamX+70)
Servo(1, CamY)
def CameraUp():
global CamX
global CamY
CamY=CamY + 100
if CamY > 3600:
CamY = 3600
CameraSet()
def CameraDown():
global CamX
global CamY
CamY=CamY - 100
if CamY < 2200:
CamY = 2200
CameraSet()
def CameraLeft():
global CamX
global CamY
CamX = CamX - 200
if CamX < 800:
CamX = 800
CameraSet()
def CameraRight():
global CamX
global CamY
CamX = CamX + 200
if CamX > 4800:
CamX = 4800
CameraSet()
def CameraHome():
global CamX
global CamY
CamX = homeX
CamY = homeY
CameraSet()
def CameraStop():
CameraSet()
CameraSet()
ServoSpeed(0,32)
ServoSpeed(1,32)
GPIO.setmode(GPIO.BOARD)
# set enable a as output
GPIO.setup(EnA,GPIO.OUT)
GPIO.output(EnA, False)
#set enable b as output
GPIO.setup(EnB,GPIO.OUT)
GPIO.output(EnB, False)
#set enable out 1,2,3 and 4 as output
GPIO.setup(Out1,GPIO.OUT)
GPIO.setup(Out2,GPIO.OUT)
GPIO.setup(Out3,GPIO.OUT)
GPIO.setup(Out4,GPIO.OUT)
GPIO.output(Out1,False)
GPIO.output(Out2,False)
GPIO.output(Out3,False)
GPIO.output(Out4,False)
server = webiopi.Server(
port=8000,
login="robot",
password="r2d2")
server.addMacro(Forward)
server.addMacro(Stop)
server.addMacro(Reverse)
server.addMacro(TurnRight)
server.addMacro(TurnLeft)
server.addMacro(OpenJaw)
server.addMacro(CloseJaw)
server.addMacro(CameraHome)
server.addMacro(CameraUp)
server.addMacro(CameraDown)
server.addMacro(CameraLeft)
server.addMacro(CameraRight)
server.addMacro(CameraStop)
server.addMacro(Play1)
server.addMacro(Play2)
server.addMacro(Play3)
server.addMacro(Play4)
server.addMacro(Play5)
server.addMacro(Play6)
server.addMacro(Play7)
server.addMacro(Play8)
server.addMacro(Play9)
webiopi.runLoop()
server.stop()



Code: Select all
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content = "height = device-height, width = 420, user-scalable = no" />
<title>Hammerstein_Mobile_Control_Panel</title>
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript">
function cam_pan_left() {
webiopi().callMacro("cam_pan_left");
}
function cam_pan_right() {
webiopi().callMacro("cam_pan_right");
}
function cam_pan_centre() {
webiopi().callMacro("cam_pan_centre");
}
function cam_tilt_up() {
webiopi().callMacro("cam_tilt_up");
}
function cam_tilt_down() {
webiopi().callMacro("cam_tilt_down");
}
function cam_tilt_centre() {
webiopi().callMacro("cam_tilt_centre");
}
function cam_stop() {
webiopi().callMacro("cam_stop");
}
webiopi().reday(init);
</script>
<style type="text/css">
.myButton {
-moz-box-shadow:inset 0px 1px 0px 0px #ffffff;
-webkit-box-shadow:inset 0px 1px 0px 0px #ffffff;
box-shadow:inset 0px 1px 0px 0px #ffffff;
background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ffffff), color-stop(1, #f6f6f6));
background:-moz-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-webkit-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-o-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-ms-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:linear-gradient(to bottom, #ffffff 5%, #f6f6f6 100%);
background-color:#ffffff;
-moz-border-radius:6px;
-webkit-border-radius:6px;
border-radius:6px;
border:1px solid #dcdcdc;
display:inline-block;
cursor:pointer;
color:#666666;
font-family:Arial;
font-size:15px;
font-weight:bold;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #ffffff;
width: 130px;
height:30px;
margin:1px;
}
.myButton:hover {
background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #f6f6f6), color-stop(1, #ffffff));
background:-moz-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-webkit-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-o-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-ms-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:linear-gradient(to bottom, #f6f6f6 5%, #ffffff 100%);
background-color:#f6f6f6;
padding:6px 24px;
}
.myButton:active {
color:#ff0000;
position:relative;
top:1px;
padding:6px 24px;
}
</style>
</head>
<body>
<center><h3>Hammerstein Control Panel</h3></center><br>
<center>
<table>
<tr><td colspan=3 align="center"><button class="myButton" onmousedown="cam_tilt_up()" onmouseup="cam_stop()">Tilt Up</but$
<tr><td><button class="myButton" type="button" onmousedown="cam_pan_left()" onmouseup="cam_stop()">Pan Left</button></td>
<td><button class="myButton" type="button" onclick="cam_stop()">Cam Stop</button></td>
<td><button class="myButton" type="button" onmousedown="cam_pan_right()" onmouseup="cam_stop()">Pan Right</button></td></$
<tr><td colspan=3 align="center"><button class="myButton" type="button" onmousedown="cam_tilt_down()" onmouseup="cam_stop$
<tr><td colspan=3 align="center"><button class="myButton" type="button" onmousedown="LED_On()" onmouseup="Stop()">LED_On<$
</table>
</center>
</body>
</html>Code: Select all
# Prior to running this program you must start the pigpio daemon by
# entering 'sudo pigpiod' at the command prompt
# To start webiopi enter 'sudo webiopi -d -c /etc/webiopi/config' at the command prompt
#!/usr/bin/env python
import webiopi
import time
import pigpio
pi = pigpio.pi()
# Start the webiopi server
# server = webiopi.Server(port=8000, login="Hammerstein", password="Hammerstein"
# Define functions
def cam_pan_left():
pi.set_servo_pulsewidth(23, 1100)
time.sleep(1)
pi.set_servo_pulsewidth(23, 0)
def cam_pan_right():
pi.set_servo_pulsewidth(23, 1900)
time.sleep(1)
pi.set_servo_pulsewidth(23, 0)
def cam_pan_centre():
pi.set_servo_pulsewidth(23, 1500)
time.sleep(1)
pi.set_servo_pulsewidth(23, 0)
def cam_tilt_up():
pi.set_servo_pulsewidth(24, 1100)
time.sleep(1)
pi.set_servo_pulsewidth(24, 0)
pi.stop()
def cam_tilt_down():
pi.set_servo_pulsewidth(24, 1900)
time.sleep(1)
pi.set_servo_pulsewidth(24, 0)
def cam_tilt_centre():
pi.set_servo_pulsewidth(24, 1500)
time.sleep(1)
pi.set_servo_pulsewidth(24, 0)
# Start the webiopi server
server = webiopi.Server(port=8000, login="", password="")
# Register the macros
server.addMacro(cam_pan_left)
server.addMacro(cam_pan_right)
server.addMacro(cam_pan_centre)
server.addMacro(cam_tilt_up)
server.addMacro(cam_tilt_down)
server.addMacro(cam_tilt_centre)
server.addMacro(cam_stop)
# Run default loop
# webiopi.runloop()
# Cleanly stop server
server.stop()
pi.stop()Code: Select all
sudo chmod -x /etc/init.d/webiopiCode: Select all
sudo service webiopi stop
Code: Select all
# Prior to running this program you must start the pigpio daemon by
# entering 'sudo pigpiod' at the command prompt
# To start webiopi enter 'sudo webiopi -d -c /etc/webiopi/config' at the command prompt
#!/usr/bin/env python
import webiopi
from time import sleep
import pigpio
pi = pigpio.pi()
# Start the webiopi server
# server = webiopi.Server(port=8000, login="UserName", password="Password"
# Define functions
#@webiopi.macro
def cam_pan_left():
pi.set_servo_pulsewidth(23, 1900)
time.sleep(1)
pi.set_servo_pulsewidth(23, 0)
#@webiopi.macro
def cam_pan_right():
pi.set_servo_pulsewidth(23, 1100)
time.sleep(1)
pi.set_servo_pulsewidth(23, 0)
#@webiopi.macro
def cam_pan_centre():
pi.set_servo_pulsewidth(23, 1500)
time.sleep(1)
pi.set_servo_pulsewidth(23, 0)
#@webiopi.macro
def cam_tilt_up():
pi.set_servo_pulsewidth(24, 1100)
time.sleep(1)
pi.set_servo_pulsewidth(24, 0)
#@webiopi.macro
def cam_tilt_down():
pi.set_servo_pulsewidth(24, 1900)
time.sleep(1)
pi.set_servo_pulsewidth(24, 0)
#@webiopi.macro
def cam_tilt_centre():
pi.set_servo_pulsewidth(24, 1500)
time.sleep(1)
pi.set_servo_pulsewidth(24, 0)
#@webiopi.macro
def cam_stop():
pi.set_servo_pulsewidth(23, 0)
pi.set_servo_pulsewidth(24, 0)
# Start the webiopi server
server = webiopi.Server(port=8000, login="Hammerstein", password="Hammerstein")
# Register the macros
server.addMacro(cam_pan_left)
server.addMacro(cam_pan_right)
server.addMacro(cam_pan_centre)
server.addMacro(cam_tilt_up)
server.addMacro(cam_tilt_down)
server.addMacro(cam_tilt_centre)
server.addMacro(cam_stop)
# Run default loop
#webiopi.runloop()
# Cleanly stop server
#server.stop()
Code: Select all
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content = "height = device-height, width = 420, user-scalable = no" />
<title>Hammerstein_Mobile_Control_Panel</title>
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript">
function cam_pan_left() {
webiopi().callMacro("cam_pan_left");
}
function cam_pan_right() {
webiopi().callMacro("cam_pan_right");
}
function cam_pan_centre() {
webiopi().callMacro("cam_pan_centre");
}
function cam_tilt_up() {
webiopi().callMacro("cam_tilt_up");
}
function cam_tilt_down() {
webiopi().callMacro("cam_tilt_down");
}
function cam_tilt_centre() {
webiopi().callMacro("cam_tilt_centre");
}
function cam_stop() {
webiopi().callMacro("cam_stop");
}
</script>
<style type="text/css">
.myButton {
-moz-box-shadow:inset 0px 1px 0px 0px #ffffff;
-webkit-box-shadow:inset 0px 1px 0px 0px #ffffff;
box-shadow:inset 0px 1px 0px 0px #ffffff;
background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ffffff), color-stop(1, #f6f6f6));
background:-moz-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-webkit-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-o-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-ms-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:linear-gradient(to bottom, #ffffff 5%, #f6f6f6 100%);
background-color:#ffffff;
-moz-border-radius:6px;
-webkit-border-radius:6px;
border-radius:6px;
border:1px solid #dcdcdc;
display:inline-block;
cursor:pointer;
color:#666666;
font-family:Arial;
font-size:15px;
font-weight:bold;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #ffffff;
width: 130px;
height:30px;
margin:1px;
}
.myButton:hover {
background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #f6f6f6), color-stop(1, #ffffff));
background:-moz-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-webkit-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-o-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-ms-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:linear-gradient(to bottom, #f6f6f6 5%, #ffffff 100%);
background-color:#f6f6f6;
padding:6px 24px;
}
.myButton:active {
color:#ff0000;
position:relative;
top:1px;
padding:6px 24px;
}
</style>
</head>
<body>
<center><h3>Hammerstein Control Panel</h3></center><br>
<center>
<table>
<tr><td colspan=3 align="center"><button class="myButton" onmousedown="cam_tilt_up()" onmouseup="cam_stop()">Tilt Up</button></td></tr>
<tr><td><button class="myButton" type="button" onmousedown="cam_pan_left()" onmouseup="cam_stop()">Pan Left</button></td>
<td><button class="myButton" type="button" onclick="cam_stop()">Cam Stop</button></td>
<td><button class="myButton" type="button" onmousedown="cam_pan_right()" onmouseup="cam_stop()">Pan Right</button></td></tr>
<tr><td colspan=3 align="center"><button class="myButton" type="button" onmousedown="cam_tilt_down()" onmouseup="cam_stop()">Tilt Down</button></td></tr>
<tr><td colspan=3 align="center"><button class="myButton" type="button" onmousedown="LED_On()" onmouseup="Stop()">LED_On</button></td></tr>
</table>
</center>
</body>
</html>
Code: Select all
webiopi.runLoop()
server.stop()
Dan;danjperron wrote:I did check my old code from my PI robot and I do have the two last lines than you remark.
but you have a typo it is webiopi.runLoop() upper case 'L'
Code: Select all
webiopi.runLoop() server.stop()
I don't know about the error. maybe it is due to the missing webiopi.runLoop()

Code: Select all
# Python programme for controlling Arduino Nano connected to a Raspberry Pi using i2c serial communication
# inspiration for the i2c element from Osar laing's Blog
# http://blog.oscarliang.net/raspberry-pi-arduino-connected-i2c
# Commands sent to Raspberry Pi over a web page using webiopi
# Prior to running this program you must start the pigpio daemon
# by either entering pigpiod at a command prompt or running it automatically at startup
# as a CRON job
# If you recieve a module import error no module named smbus ensure version of smbus
# and WebIOPi Python match
#/usr/bin/env python
import webiopi # Import webiopi - software to communicate with a Rapsberry Pi over a web interface
import smbus as smbus
import time
import pigpio # pigpio is a custom module for controlling GPIO pins
pi = pigpio.pi #declare psuedo for pigpio commands
bus = smbus.SMBus(1) # For RPI version 1 use "bus = smbus.SMBus(0)"
# Setup i2C communication address (must be the same as address set on Arduino
address = 0x04
def writeNumber(value):
bus.write_byte(address, value)
# bus.write_byte_data(address, 0, value)
return -1
def readNumber():
number = bus.read_byte_data(address, 1)
return number
#@webiopi.macro
def stop():
number = 0
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def forward():
number = 1
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def left():
number = 2
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def right():
number = 3
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def backward():
number = 4
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def servo_centre():
number = 5
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def servo_left():
number = 6
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def servo_right():
number = 7
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def led_on():
number = 8
writeNumber(number)
time.sleep(1)
#@webiopi.macro
def led_off():
number = 9
writeNumber(number)
time.sleep(1)
# Start the webiopi server
server = webiopi.Server(port=8000, login="Hammerstein", password="Hammerstein")
# Register the macros
server.addMacro(stop)
server.addMacro(forward)
server.addMacro(left)
server.addMacro(right)
server.addMacro(backward)
server.addMacro(stop)
server.addMacro(servo_centre)
server.addMacro(servo_left)
server.addMacro(servo_right)
server.addMacro(led_on)
server.addMacro(led_off)
# Run default loop
webiopi.runLoop()
# Cleanly stop the server
server.stop()
Code: Select all
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content = "height = device-height, width = 420, user-scalable = no" />
<title>Hammerstein_Mobile_Control_Panel</title>
<script type="text/javascript" src="/webiopi.js"></script>
<script type="text/javascript">
function stop() {
webiopi().callMacro("stop");
}
function forward() {
webiopi().callMacro("forward");
}
function left() {
webiopi().callMacro("left");
}
function right() {
webiopi().callMacro("right");
}
function backward() {
webiopi().callMacro("backward");
}
function servo_centre() {
webiopi().callMacro("servo_centre");
}
function servo_left() {
webiopi().callMacro("servo_left");
}
function servo_right() {
webiopi().callMacro("servo_right");
}
function LED_On() {
webiopi().callMacro("led_on");
}
function LED_Off() {
webiopi().callMacro("led_off");
}
</script>
<style type="text/css">
.myButton {
-moz-box-shadow:inset 0px 1px 0px 0px #ffffff;
-webkit-box-shadow:inset 0px 1px 0px 0px #ffffff;
box-shadow:inset 0px 1px 0px 0px #ffffff;
background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ffffff), color-stop(1, #f6f6f6));
background:-moz-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-webkit-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-o-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:-ms-linear-gradient(top, #ffffff 5%, #f6f6f6 100%);
background:linear-gradient(to bottom, #ffffff 5%, #f6f6f6 100%);
background-color:#ffffff;
-moz-border-radius:6px;
-webkit-border-radius:6px;
border-radius:6px;
border:1px solid #dcdcdc;
display:inline-block;
cursor:pointer;
color:#666666;
font-family:Arial;
font-size:15px;
font-weight:bold;
padding:6px 24px;
text-decoration:none;
text-shadow:0px 1px 0px #ffffff;
width: 130px;
height:30px;
margin:1px;
}
.myButton:hover {
background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #f6f6f6), color-stop(1, #ffffff));
background:-moz-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-webkit-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-o-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:-ms-linear-gradient(top, #f6f6f6 5%, #ffffff 100%);
background:linear-gradient(to bottom, #f6f6f6 5%, #ffffff 100%);
background-color:#f6f6f6;
padding:6px 24px;
}
.myButton:active {
color:#ff0000;
position:relative;
top:1px;
padding:6px 24px;
}
</style>
</head>
<body>
<center><h3>Hammerstein Control Panel</h3></center><br>
<center>
<table>
<tr><td colspan=3 align="center"><button class="myButton" onmousedown="forward()" onmouseup="stop()">Forward</button></td></tr>
<tr><td><button class="myButton" type="button" onmousedown="left()" onmouseup="stop()">Left</button></td>
<td><button class="myButton" type="button" onclick="stop()">Stop</button></td>
<td><button class="myButton" type="button" onmousedown="right()" onmouseup="stop()">Right</button></td></tr>
<tr><td colspan=3 align="center"><button class="myButton" type="button" onmousedown="backward()" onmouseup="stop()">Backward</button></td></tr>
<tr><td colspan=3 align="center"><button class="myButton" type="button" onmousedown="LED_On()" onmouseup="LED_Off()">LED_On</button></td></tr>
</table>
</center>
<center><h3>Sensor Control</h3></center><br>
<center>
<table>
<tr><td><button class="myButton" type="button" onclick="servo_left()">Scan Left</button></td>
<td><button class="myButton" type="button" onclick="servo_centre()">Centre</button></td>
<td><button class="myButton" type="button" onclick="servo_right()">Scan Right</button></td></tr>
</table>
</center>
</body>
</html>
Code: Select all
// Arduino Pin A5 to RPi SDA
// Arduino Pin A6 to RPi SCL
// Inspiration from Ocra Laing's Blog http://blog.oscarliang.net/raspberry-pi-arduino-connected-i2c
#include <Wire.h>
#include <Servo.h>
#define SLAVE_ADDRESS 0x04
int number = 0;
int state = 0;
// Setup Ultrasonic Sensor Pins
#define trigPin 12
#define echoPin 13
// Defines for reading distances
#define microsecondsToCentimeters(microseconds) (unsigned long)microseconds / 29.1 / 2.0
#define MinActionDistance 40 // Set maximum allowaable distance to obstacle
// Setup motor controller pins for L298N
// Right Motor
int enA = 11;
int in1 = 8;
int in2 = 7;
//Left Motor
int enB = 4;
int in3 = 6;
int in4 = 5;
// Setup LED test pin
int Led = 10;
// Setup the servo
Servo myservo;
byte sweep_pos = 0;
byte pos_index = 90;
unsigned long left_dist, right_dist;
//Set unsigned integer variables to be used
unsigned int duration;
unsigned int distance;
unsigned int FrontDistance;
unsigned int LeftDistance;
unsigned int RightDistance;
void setup() {
Serial.begin(9600); // Start serial for output
Wire.begin(SLAVE_ADDRESS); // Initialise i2c as slave
//Define callbacks for i2c communication
Wire.onReceive(receiveData);
Wire.onRequest(sendData);
//Setup the servo
myservo.attach(2); //Attaches the servo to pin 2 of the Nano
myservo.write(90); //Set the servo to face front
//Below set all the pin modes as OUTPUT as they will all be outputting data
//Set modes for distance sensor pins
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
//Set modes for motor controller pins
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
//Set mode for Led test pin
pinMode(Led, OUTPUT);
// Declare ready
Serial.println("Hammerstein Ready!");
}
void loop() {
delay(100);
unsigned long dist_fwd;
//Rotate the sensor to check for obstacles
//scan(); //Call the scan function
ping();
}
// Callback for received data
void receiveData(int byteCount) {
while(Wire.available()) {
number = Wire.read();
Serial.println("data received: ");
Serial.println(number);
if (number == 0) {
Stop();
}
if (number == 1) {
Forward();
}
if (number == 2) {
Left();
}
if (number == 3) {
Right();
}
if (number == 4) {
Backward();
}
if (number == 5) {
Servo_Centre();
}
if (number == 6) {
Servo_Left();
}
if (number == 7) {
Servo_Right();
}
if (number == 8) {
led_on();
}
if (number == 9) {
led_off();
}
}
}
// Callback for sending data
void sendData() {
Wire.write(number);
}
void scan() //This function tells the robot to scan for obstacles
{
if (sweep_pos <=0) {
pos_index = 20;
}
else if (sweep_pos >=180) {
pos_index = -20;
}
Serial.print ("pos_index = ");
Serial.println(pos_index);
sweep_pos += pos_index;
Serial.print("sweep_pos = ");
Serial.println(sweep_pos);
myservo.write (sweep_pos);
}
void Servo_Centre()
{
Serial.println("");
Serial.println("Scanning Forward");
if (sweep_pos != 90) {
myservo.write(90);
sweep_pos = 90;
}
}
void Servo_Right()
{
Serial.println("");
Serial.println("Scanning Right");
if (sweep_pos != 20) {
myservo.write(20);
sweep_pos = 20;
}
}
void Servo_Left()
{
Serial.println("");
Serial.println("Scanning Left");
if (sweep_pos != 160) {
myservo.write(160);
sweep_pos = 160;
}
}
void led_on()
{
Serial.println("");
Serial.println("Led On");
digitalWrite(Led, HIGH);
}
void led_off()
{
Serial.println("");
Serial.println("Led Off");
digitalWrite(Led, LOW);
}
//Read the HC-SR04 sensor
unsigned long ping()
{
//Trigger the sensor to send out a ping
digitalWrite (trigPin, LOW);
delayMicroseconds (5);
digitalWrite (trigPin, HIGH);
delayMicroseconds (10);
//Measure how long the ping took to return and convert to centimeters
return (microsecondsToCentimeters (pulseIn (echoPin, HIGH)));
}
void Forward() //This function tells the robot to go forward
{
Serial.println("");
Serial.println("Moving forward");
// turn on left motor
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// set speed out of possible range 0~255
analogWrite(enA, 245);
// turn on right motor
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// set speed out of possible range 0~255
analogWrite(enB, 130);
//delay(100);
}
void Backward() //This function tells the robot to move backward
{
Serial.println("");
Serial.println("Moving backward");
// turn on left motor
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// set speed out of possible range 0~255
analogWrite(enA, 245);
// turn on right motor
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
// set speed out of possible range 0~255
analogWrite(enB, 130);
//delay(100);
}
void Left() //This function tells the robot to turn left
{
Serial.println("");
Serial.println("Moving left");
digitalWrite(in1, LOW);
digitalWrite(in2, HIGH);
// set speed out of possible range 0~255
analogWrite(enA, 245);
digitalWrite(in3, LOW);
digitalWrite(in4, HIGH);
// set speed out of possible range 0~255
analogWrite(enB, 130);
//delay(100);
}
void Right() //This function tells the robot to turn right
{
Serial.println("");
Serial.println("Moving right");
digitalWrite(in1, HIGH);
digitalWrite(in2, LOW);
// set speed out of possible range 0~255
analogWrite(enA, 245);
digitalWrite(in3, HIGH);
digitalWrite(in4, LOW);
analogWrite(enB, 130);
//delay(100);
}
void Stop() //This function tells the robot to stop moving
{
Serial.println("");
Serial.println("Stopping");
// now turn off motors
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
analogWrite(enA, 0);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
analogWrite(enB, 0);
}

No worries, happy to pass on anything I can to help, I am hoping to get the Robot put back together for our Pi Jam on Saturday, I'll post up some Pics.Rovracing wrote:cool project - I'll PM you with some questions.
-p