Hola a todos, quiero pedir ayuda para poder ejecutar este ejemplo que es muy completo que nos da makeblock.
Estoy con este proyecto y hasta ahora he logrado buscar los programas necesarios y ejecutar los script de python que habilita para el stream de video, que no de error de ttyAMA0, que los dos joystick envien señal de cada mando y meter el firmware en la placa Orion corrigiendo fallos de compilación.
Aun queda comunicar la raspberry Pi2 con la placa Orion, desde el navegador web ya envía la señal de cada boton pero no logro que la placa orion reconozca estas señales que envia la web y via serie a traves del Shield ponga en marcha los motores y los servos de barrido vertical y horizontal de la cámara.
Mas abajo dejare el codigo ya modificado y que está funcionado así como los script de python que he usado
He buscado en varios foros y sitios web como usar y que funcionen los ejemplos del repositorio Makeblock oficial link: Repositorio RaspberryShield Oficial. Pero ninguno ha funcionado igualmente . dejo los link de los dos sitios que encontré información.
Me for Raspberry Pi Aqui Anthony muestra su modelo y explica que ha logrado que funcione el codigo pero no logra compartir el firmware.ino que va a la placa Orion.
En esta otra Enviar instrucciones mediante Raspberry Pi a través de MeShield for Raspberry Pi comparte un codigo que envía señales usando el modulo bluethoot pero no explica como lo pone en marcha.
Con esto llevo semanas intentando comunicar la raspberry con el shield aqui explico mi experiencia y avance para que me puedan ayudar.
Este ejemplo webcam_car, que está dentro de la carpeta RaspberryShield/webcam_car/firmware/ el firmware.ino, lo he compilado con Arduino.cc IDE 1.6.9 añadiendo todas las librerías makeblock, al compilarla encuentro el primer error no es compatible para la placa Orion con microcontrolador Atmega 328P a pesar de contener las configuraciones para este micro, según analicé está pensado para la placa Meboard que lleva microcontrolador Atmega 32u4 que usa el arduino leonardo del starter kit v1.
He logrado copilar el código y meterla en la placa Orion.
Para ello he realizado lo siguiente:
He comentado con // la parte que usa micro 32u4.
en especial Serial1 pues esta instrucción lo usa el micro 32u4 y no el 328P.generando aqui el error de compatibilidad.
Cambie los puertos que pertenece a Meboard para los servos al 8 y 2 válidos del Orion.
He descargado la libreria OneWire e instalado en la libreria del IDE porque daba error al no encontrar instalada la libreria OneWire.
Por ultimo gracias a un post de arduino añadí en la librería main.cpp ubicada en arduino-1.6.9\hardware\arduino\avr\cores\arduino
lo siguiente loop(); añadir void loop();
ya que genera error -1 por este bucle infinito. Aunque parezca una tontería es un error que daba mucho dolor de cabeza a varias personas.
main.cpp
#include <Arduino.h>
// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }
// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
void setupUSB() __attribute__((weak));
void setupUSB() { }
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
void loop();// originalmente viene loop();
if (serialEventRun) serialEventRun();
}
return 0;
}
firware.ino
#include <SoftwareSerial.h>
#include <Wire.h>
#include <String.h>
#include <OneWire.h>
#include "Servo.h"
#define NC -1
#define NUM_QUERYLIST 10
#define SLOT1 0
#define SLOT2 1
#define PORT_1 0x01
#define PORT_2 0x02
#define PORT_3 0x03
#define PORT_4 0x04
#define PORT_5 0x05
#define PORT_6 0x06
#define PORT_7 0x07
#define PORT_8 0x08
#define M1 0x09
#define M2 0x0a
#define NOP __asm__("nop\n\t")
#define HIGH0 *P_RGB = PINON;*P_RGB = PINOFF;
#define HIGH1 *P_RGB = PINON;NOP;NOP;NOP;NOP;*P_RGB = PINOFF;
#define buzzerOn() DDRE |= 0x04,PORTE |= B00000100
#define buzzerOff() DDRE |= 0x04,PORTE &= B11111011
#if defined(__AVR_ATmega32U4__) //MeBaseBoard use ATmega32U4 as MCU
unsigned char mePort[11][2] = {{NC, NC}, {11, A8}, {13, A11}, {A10, A9}, {1, 0},
{MISO, SCK}, {A0, A1}, {A2, A3}, {A4, A5}, {6, 7}, {5, 4}
};
#else // else ATmega328
unsigned char mePort[11][2] = {{NC, NC}, {11, 10}, {3, 9}, {12, 13}, {8, 2},
{NC, NC}, {A2, A3}, {NC, A1}, {NC, A0}, {6, 7}, {5, 4}
};
#endif
Servo servox,servoy;
void doDcRun(char port, int speed)
{
char dpin,apin;
dpin = mePort[port][1]; // digit pin
apin = mePort[port][0]; // analog pin
speed = speed > 255 ? 255 : speed;
speed = speed < -255 ? -255 : speed;
if(speed >= 0) {
pinMode(dpin, OUTPUT);
digitalWrite(dpin, HIGH);
analogWrite(apin, speed);
} else {
pinMode(dpin, OUTPUT);
digitalWrite(dpin, LOW);
analogWrite(apin, -speed);
}
}
void parseCmd(char * cmd){
Serial.println(cmd);
if(cmd[0]=='M'){
int spd0,spd1;
sscanf(cmd,"M:%d,%d\n",&spd0,&spd1);
doDcRun(M1,spd0);
doDcRun(M2,spd1);
}else if(cmd[0]=='H'){
int pos0,pos1;
sscanf(cmd,"H:%d,%d\n",&pos0,&pos1);
servox.write(pos0);
servoy.write(pos1);
}
}
void setup() {
Serial.begin(115200);
// Serial1.begin(115200);
servox.attach(8);
servoy.attach(2);
servox.write(90);
servoy.write(90);
}
/*char buf[64];
char bufIndex=0;
void loop() {
if(Serial1.available()){
char c = Serial1.read();
Serial.write(c);
buf[bufIndex++]=c;
if(c=='\n'){
parseCmd(buf);
bufIndex = 0;
memset(buf,0,64);
}
}
}
*/
Aquí adjunto el código python que genera la web y habilita los joystick para enviar las señales a la placa orion a través del shield, aquí es donde necesito la ayuda para saber si es aquí o en el firmware.ino el problema que no tengo la comunicación para que active los motores y servos .
import web
import serial
import threading
import socket
import fcntl
import struct
import time
port1=1
port2=2
port3=3
port4=4
port5=5
port6=6
port7=7
port8=8
m1=9
m2=10
slot1=0
slot2=1
DEV_NULL= "NULL"
DEV_ULTRASONIC= "Ultrasonic Sensor"
DEV_PIR= "PIR Motion Sensor"
DEV_BUTTON= "Button"
DEV_LIMIT= "Limit Switch"
DEV_POTENTIO= "Potentiometer"
DEV_LINEFINDER= "Line Finder"
DEV_SOUNDSENSOR= "Sound Sensor"
DEV_TEMPERATURE= "Temperature Sensor"
DEV_DCMOTOR= "DC Motor"
DEV_SERVO= "Servo Motor"
DEV_JOYSTICK= "Joystick"
DEV_LED= "Led"
DEV_IR= "Ir"
DEV_DPORT_READ= "R_DPORT"
DEV_APORT_READ= "R_APORT"
DEV_DPORT_WRITE= "W_DPORT"
DEV_APORT_WRITE="W_APORT"
class serialRead(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while True:
l = ser.readline()
#print l
parseEcho(l)
def isNumber(txt):
try:
int(txt,0)
return True
except:
return False
def runmotor(left,right):
cmd = "M:%d,%d\n" %(left,right)
ser.write(cmd)
print cmd
def runservo(axisx,axisy):
cmd = "H:%d,%d\n" %(axisx,axisy)
ser.write(cmd)
print cmd
webtxt="""
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#joystick{
position: absolute;
top: 271px;
left: 10px;
}
#head{
position: absolute;
top: 271px;
left: 695px;
}
#distance{
position: absolute;
top: 10px;
left: 10px;
font-size:25px;
color:#ff3300
}
</style>
<script type="text/javascript">
//window.setInterval(getdistance,500)
function getdistance()
{
dis = httpGet("/poll")
console.log("distance",dis)
document.getElementById("distance").innerHTML = dis
}
function httpGet(theUrl)
{
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false );
xmlHttp.send( null );
return xmlHttp.responseText;
}
</script>
</head>
<body>
<div id="joystick">
<img src="static/ctrl.png" usemap="#pad1" width="320" height="310" border="0">
<map name="pad1">
<area shape="rect" coords="124,41,195,113" onclick=httpGet("?move=forward") target="Message" alt="Move Forward" title="Move Forward">
<area shape="rect" coords="38,118,117,191" onclick=httpGet("?move=left") target="Message" alt="Move Left" title="Move Left">
<area shape="rect" coords="209,121,274,191" onclick=httpGet("?move=right") target="Message" alt="Move Right" title="Move Right">
<area shape="rect" coords="126,196,195,268" onclick=httpGet("?move=backward") target="Message" alt="Move Backward" title="Move Backward">
<area shape="rect" coords="128,126,196,188" onclick=httpGet("?move=stop") target="Message" alt="Stop" title="Stop">
</map>
</div>
<div id="head">
<img src="static/ctrl.png" usemap="#pad2" width="320" height="310" border="0">
<map name="pad2">
<area shape="rect" coords="124,41,195,113" onclick=httpGet("?head=up") target="Message" alt="Head Up" title="Head Up">
<area shape="rect" coords="38,118,117,191" onclick=httpGet("?head=left") target="Message" alt="Head Left" title="Head Left">
<area shape="rect" coords="209,121,274,191" onclick=httpGet("?head=right") target="Message" alt="Head Right" title="Head Right">
<area shape="rect" coords="126,196,195,268" onclick=httpGet("?head=down") target="Message" alt="Head Down" title="Head Down">
<area shape="rect" coords="128,126,196,188" onclick=httpGet("?head=origin") target="Message" alt="Back to Origin" title="Back to Origin">
</map>
</div>
<div>
<iframe src="http://HOSTIP:9000/stream_simple.html" width="100%" height="750" frameborder="no" border="0" marginwidth="0" marginheight="0" scrolling="no" allowtransparency="yes"></iframe>
</div>
<div id="distance">
@DIS
</div>
</body>
</html>
"""
urls = (
'/', 'index',
"/poll", "poll",
)
class index:
def GET(self):
global distance,posx,posy,spdl,spdr
user_data = web.input()
if user_data.has_key("move") :
if user_data.move == "forward":
spdl = 80
spdr = 80
elif user_data.move == "backward":
spdl = -80
spdr = -80
elif user_data.move == "left":
spdl -= 20
spdr += 20
elif user_data.move == "right":
spdl += 20
spdr -= 20
elif user_data.move == "stop":
spdl = 0
spdr = 0
runmotor(spdl,spdr)
if user_data.has_key("head"):
print "head",user_data.head
if user_data.head=="up":
posx+=10
elif user_data.head=="left":
posy+=10
elif user_data.head=="right":
posy-=10
elif user_data.head=="down":
posx-=10
elif user_data.head == "origin":
posx = 90
posy = 90
if posx>=180:posx=180
if posx<=0:posx=0
if posy>=180:posy=180
if posy<=0:posy=0
runservo(posx,posy)
print distance
strr = webtxt.replace("@DIS","%d cm" %(distance))
return strr
class poll:
def GET(self):
global distance
return "%d cm" %distance
def get_ip_address(ifname):
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915,
struct.pack('256s',ifname[:15])
)[20:24])
localIp = get_ip_address('wlan0')
print "localip =",localIp
webtxt = webtxt.replace("HOSTIP", localIp)
ser = serial.Serial('/dev/ttyAMA0', 115200)
#th = serialRead()
#th.setDaemon(True)
#th.start()
spdl = 0
spdr = 0
posx = 90
posy = 90
distance = 0
runservo(posx,posy)
runmotor(spdl,spdr)
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
Dejo el script ./run.sh
cd /home/pi/RaspberryShield/webcam_car
./star_stream.sh &
cd /home/pi/RaspberryShield/webcam_car
python starterkit_webcam.py &
este es el script para iniciar el stream
start_stream.sh
#!/bin/bash
if pgrep mjpg_streamer > /dev/null
then
echo "mjpg_streamer already running"
else
LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i "input_raspicam.so -fps 15 -q 50 -x 640 -y 480" -o "output_http.so -p 9000 -w /opt/mjpg-streamer/www" > /dev/null 2>&1&
echo "mjpg_streamer started"
fi
y tengo otro para poder parar el stream
stop_stream.sh
#!/bin/bash
if pgrep mjpg_streamer
then
kill $(pgrep mjpg_streamer) > /dev/null 2>&1
echo "mjpg_streamer stopped"
else
echo "mjpg_streamer not running"
fi
Para poder configurar el stream correctamente añado la pagina con la cual me basé para dejarla correcta y con el menor lag posible
Pi camara video streaming gracias a Miguel Mota
y para poder configurar el puerto serie correctamente pues si solo se desactiva el puerto serie. Si se usa sudo raspi-conf desactiva completamente el purto ttyAMA0 y no hay manera de que funcione esto esta en la pagina oficial de makeblock.
Usando el puerto serie de la Raspberry Pi
Ahora para probar si esta correctamente habilitado usamos este comando
dmesg | grep tty
Y debe aparecer esto
pi@Ale_Pi:~ $ dmesg | grep tty
[ 0.000000] Kernel command line: dma.dmachans=0x7f35 bcm2708_fb.fbwidth=656 bcm2708_fb.fbheight=416 bcm2709.boardrev=0xa01041 bcm2709.serial=0xf6da777f smsc95xx.macaddr=B8:27:EB:DA:77:7F bcm2708_fb.fbswap=1 bcm2709.uart_clock=3000000 bcm2709.disk_led_gpio=47 bcm2709.disk_led_active_low=0 vc_mem.mem_base=0x3dc00000 vc_mem.mem_size=0x3f000000 dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
[ 0.001523] console [tty1] enabled
[ 0.091976] 3f201000.uart: ttyAMA0 at MMIO 0x3f201000 (irq = 87, base_baud = 0) is a PL011 rev2
y para mostrar la URL en el navegador web debemos instalar webPi dentro de la raspberry pi
siguiendo este tutorial
Instalar webPi
Cualquier avance postearlo aquí espero podamos sacar mas probecho de este ejemplo