Programmazione lato PC

Added by Andrea Belloni almost 4 years ago

Per programmare i robot dal PC collegato via bluetooth (vista come una seriale) userei Snap4Arduino (http://s4a.cat/snap/) è basato su Snap (http://snap.berkeley.edu/), una versione estesa di Scratch dell'università di Berkeley, e contiene già le estensioni per usare Arduino tramite dei blocchi aggiuntivi. E' open source e può essere scaricato come applicazione installabile per Linux, Mac, Windows.


Replies (39)

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

Sto provando a modificare StandardFirmata firmware per accettare nuovi comandi, comandi inviati da Snap4Arduino tramite nuovi blocchi custom.

I nuovi comandi dovrebbero essere del tipo:

forward(float distance)
backward(float distance)
right(float degrees)
left(float degrees)
done()
penup()
pendown()

Vediamo se riusciamo nell'impresa.

P.S. chiunque volesse dare un aiuto è il benvenuto.

bye

Links Utili:
https://github.com/firmata/arduino/blob/master/examples/StandardFirmata/StandardFirmata.ino
http://www.instructables.com/files/orig/F2Y/6NEI/IFD6JWBV/F2Y6NEIIFD6JWBV.ino
http://blog.s4a.cat/2015/03/13/Extending-Firmata-for-Snap4Arduino.html

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

Aggiornamenti:
sono riuscito ad inviare il comando per far muovere i motori stepper ma non il servo :(

Problemi: se impartisco un movimento lungo agli stepper, la comunicazione seriale con Snap4Arduino si interrompe presentando un messaggio d'errore nel programma del PC, riprendendo in automatico dopo aver concluso il movimento.

Continuo il lavoro, quando sarò arrivato ad una versione condivisibile, l'aggiungerò nei files di questo progetto.

I Blocchi custom in Snap4Arduino si possono facilmente esportare in un file xml e reimportare.

RE: Programmazione lato PC - Added by Michele Vece almost 4 years ago

Il problema è sicuramente legato al codice pieno zeppo di delay nella porzione di codice che conrolla i motori stepper. Si potrebbero usare i millis al posto dei delay vedi qui
Consiglio di provare ad usare la libreria AccelStepper.h ( link1 link2) per il controllo motori. Io ci ho avuto a che fare qui ma non la conosco a fondo.
In alternativa c'è anche la libreria stepper.h di arduino che non ho mai usato.

RE: Programmazione lato PC - Added by Michele Vece almost 4 years ago

Qui c'è un esempio chiaro di uso della libreria Accelstepper.h con i nostri motori.
Nella stessa pagina c'è anche un esempio di Stepper.h

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

Sono riuscito a programmare tutti i movimenti utilizzando solo i blocchi di Snap4Arduino, senza modificare lo StandardFirmata.ino
Con questo approccio ci sono dei lati postivi: il firmware caricato nell'arduino è quello originale;
e negativi: i movimento dei motori stepper dipendono molto dalla seriale che gli invia ripetutamente i comandi.

Riporto a titolo d'esempio il codice del blocco forward(distance):

var wheel_dia=64.5; 
var wheel_base=114.5;
var steps_rev=512; 
var delay_time=6; 
var L_stepper_pins = [10, 12, 13, 11];
var R_stepper_pins = [3, 5, 6, 4]; 
var fwd_mask =  [[1, 0, 1, 0], [0, 1, 1, 0], [0, 1, 0, 1], [1, 0, 0, 1]]; 
var rev_mask =  [[1, 0, 0, 1], [0, 1, 0, 1], [0, 1, 1, 0], [1, 0, 1, 0]]; 
var steps = distance * steps_rev / (wheel_dia * 3.1412);
for(step = 0; step < steps; step++ ) { 
 for(mask = 0; mask < 4; mask++ ) { 
 for(pin = 0; pin < 4; pin++ ) { 
 this.arduino.board.digitalWrite(L_stepper_pins[pin], rev_mask[mask][pin]); 
 this.arduino.board.digitalWrite(R_stepper_pins[pin], fwd_mask[mask][pin]); 
 } 
 setTimeout('', delay_time); 
} 
}

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

Ho provato un Arduino Uno e un Nano entrambi con CH340G
e un Arduino Uno con FTDI, tutti hanno il problema della disconnessione,
ed ora credo di aver anche individuato il motivo,

in pratica Snap4Arduino invia un ping all'Arduino ogni 5 secondi, se invio una serie di comandi a raffica (che sono quelli per far muovere i motori Stepper)
subito dopo il ping (si nota perche RX lampeggia) non ci sono problemi, mentre se conto approssivamente 4 secondi dopo il ping ed invio la raffica, probabilmente
Snap4Arduino non riesce a ricevere la risposta del ping in tempo utile e determina la disconnessione.

Non so se è possibile aumentare il timeout del ping o addirittura disabilitarlo?!?

continua...

RE: Programmazione lato PC - Added by Moreno Petrucci almost 4 years ago

Notevole questo Snap!

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

per modificare Snap4Arduino...

in pratica ho scoperto che il file nw.exe non è altro che una specie di Chromium (browser web)
che esegue Snap4Arduino tramite il comando:

"C:\Program Files (x86)\Snap4Arduino\nw.exe" app.nw

così mi è venuto in mente di vedere se app.nw è uno zip (e lo è)...
ho scompattato lo zip app.nw nella cartella app
ho modificato lo script di avvio dell'applicazione in:

"C:\Program Files (x86)\Snap4Arduino\nw.exe" ./app/

e Snap4Arduino è partito.. ora vedo se posso fare qualcosa all'interno di questi files ;D

continua...

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

trovata la funzione arduino keepAlive in .\app\s4a\objects.js
che guarda caso è eseguita ogni 5 secondi,
vediamo se è questa e se si può modificare.

stay tuned

to be continued...

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

Ci siamo... FUNZIONAAA!!!

ho commentato la riga 163 del file .\app\s4a\objects.js in questo modo
//myself.arduino.keepAliveIntervalID = setInterval(myself.arduino.keepAlive, 5000);
oppure si può cambiare anche in questo modo:
myself.arduino.keepAliveIntervalID = setTimeout(myself.arduino.keepAlive, 5000);
in quest'ultimo modo, viene eseguito il keepAlive solo la prima volta.

in questo modo non fa più il controllo della connessione (si ok, questo significa che non determinerà più se viene disconnesso manualmente, ma possiamo farne a meno no?)
ora si può far muovere il robot per tutto il tempo che si vuole, senza preoccuparci di far durare i movimenti meno di 5 secondi.

Inoltre ho fatto un'altra piccola personalizzazione al programma Snap4Arduino, Vediamo chi se ne accorge (vede foto allegata)...

P.S. ho notato che così, la connessione iniziale impiega qualche secondo di più...

Snap4Arduino.jpg (166 KB)

RE: Programmazione lato PC - Added by Michele Vece almost 4 years ago

Puoi creare un sistema tipo "gcode" che mandi a snap conferma dell'esecuzione dei comandi al posto del controllo a tempo della connessione?
Tipo:
snap manda G0 L+100 R-100
Robot risponde OK (quando ha finito l'esecuzione del comando)
E così via...

RE: Programmazione lato PC - Added by Andrea Belloni almost 4 years ago

Per fare quello che dici te [Michele] bisognerebbe modificare firmata per eseguire comandi tipo vai avanti per N passi [o X cm] e da snap inviare un singolo messaggio cper eseguire il comando, questa secondo me è la strategia migliore e mi sembra che inizialmente Andrea era partito su questa linea, poi ha trovato degli intoppi e ha cambiato startegia [Andrea corregimi se sbaglio]. Se riesco a trovare un po' di tempo vedo se si riesce a mandare da snap comandi singoli per azioni più complesse [coordinandomi con Andrea].

Oggi mi piacevano le parentesi quadre.

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

AdvancedFirmata è questa?
https://github.com/soundanalogous/Breakout/tree/master/firmware/AdvancedFirmata

Breakout è un progetto cha ha sviluppato una versione custom di firmata per gestire anche i motori stepper tramite FirmataStepper.h / cpp
è del 14 ago 2014 mentre firmata 2.5.0 è del 8 nov 2015

provo a vedere come funziona l'attuale AdvancedFirmata...

studio in corso...

RE: Programmazione lato PC - Added by Andrea Belloni almost 4 years ago

Qui
https://github.com/firmata/arduino/issues/61
c'è l'autore stesso che consiglia di usare ConfigurableFirmata
https://github.com/firmata/ConfigurableFirmata
o AdvancedFirmata
https://github.com/soundanalogous/AdvancedFirmata
anche se consiglia il primo (entrambi hanno cose in più rispetto a StandardFirmata tra cui gli stepper)

ciao

RE: Programmazione lato PC - Added by Andrea Belloni almost 4 years ago

Come già sviscerato da Andrea C. Snap è stato sviluppato usando node-webkit
https://github.com/nwjs/nw.js

E' un tool interessante usa Node.js e WebKit (il motore rendering di chromium), può essere utile a chi conosce bene la programmazione web (HTML5, CSS3, JS and WebGL) e vuole usarla per creare applicazioni desktop
https://strongloop.com/strongblog/creating-desktop-applications-with-node-webkit/

ciao

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

credo che il progetto https://github.com/firmata/ConfigurableFirmata
sia confluito (mergiato) in https://github.com/firmata/arduino

infatti in:
https://github.com/firmata/arduino/blob/master/Firmata.h

è presente il comando (riga 49):
#define STEPPER_DATA 0x72 // control a stepper motor

ora quello che mi manca è un esempio di come si configura e come si muove uno stepper con questo metodo...

qui dovrei trovare il tutto...
https://github.com/soundanalogous/Breakout/blob/master/src/io/Stepper.js

studio in corso...

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

ok provato con https://github.com/firmata/ConfigurableFirmata
e il seguente blocco in snap funziona correttamente (invia un solo comando seriale poi arduino pensa al resto):

// private static constants
var STEPPER = 0x72                                
CONFIG = 0,                                
STEP = 1,
DRV_4WIRE = 0x04,
MAX_STEPS = 2097151, // 21 bits (2^21 - 1) 
MAX_SPEED = 16383, // 14 bits (2^14 - 1)
directionPin = 3,
stepPin = 5,
motorPin3 = 6,
motorPin4 = 4,    
CLOCKWISE = 0,
COUNTER_CLOCKWISE = 1;

var numStepsPerRev = 128;

var numStepsPerRevLSB = numStepsPerRev & 0x007F,
numStepsPerRevMSB = (numStepsPerRev >> 7) & 0x007F;

var numSteps = 1000;
var steps = [
    Math.abs(numSteps) & 0x0000007F,
    (Math.abs(numSteps) >> 7) & 0x0000007F,
    (Math.abs(numSteps) >> 14) & 0x0000007F
];

var speed = 13;
speed = Math.floor(speed.toFixed(2) * 100);
var speedLSB = speed & 0x007F;
var speedMSB = (speed >> 7) & 0x007F;                                
//this.arduino.board.pinMode(directionPin, this.arduino.board.MODES.OUTPUT);
//this.arduino.board.pinMode(stepPin, this.arduino.board.MODES.OUTPUT);
//this.arduino.board.pinMode(motorPin3, this.arduino.board.MODES.OUTPUT);
//this.arduino.board.pinMode(motorPin4, this.arduino.board.MODES.OUTPUT);

this.arduino.board.sp.write(new Buffer([0xF0,STEPPER,CONFIG,0,DRV_4WIRE,numStepsPerRevLSB,numStepsPerRevMSB,directionPin,stepPin,motorPin3,motorPin4,0xF7])); 
this.arduino.board.sp.write(new Buffer([0xF0,STEPPER,STEP,0,CLOCKWISE,steps[0],steps[1],steps[2],speedLSB,speedMSB,0xF7])); 
//this.arduino.board.sp.write(new Buffer([0xF0,STEPPER,STEP,0,COUNTER_CLOCKWISE,steps[0],steps[1],steps[2],speedLSB,speedMSB,0xF7]));                                 

per ragion di cronaca ho provato lo stesso codice in StandardFirmata e non va... probabilmente hanno riportato solo il comando nel codice:
#define STEPPER_DATA 0x72 // control a stepper motor
ma non è ancora implementato... oppure si configura in altro modo...

studio in corso...

RE: Programmazione lato PC - Added by Andrea Belloni almost 4 years ago

Ottimo
penso che ConfigurableFirmata sia la scelta giusta

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

non c'è bisogno neanche della versione custom di Snap quella a cui avevo tolto il KeepAlive, perche anche quando si muovono gli stepper, firmata risponde al KeepAlive.
però questo fa nascere un'altro problema... nell'ottica di farlo disegnare con una sequenza di movimenti... ho verificato che quando ad es...

1)pendown
2)forward di 50 cm
3)penup

subito dopo aver inviato il comando di effettuare il movimento (2), esegua anche il blocco successivo, alza penna (3) senza attendere che abbia percorso i 50 cm...

si dovrà verificare se c'è un modo per interrogare firmata (magari anche in polling o magari in callback) per capire quando il movimento è terminato e uscire dal blocco solo in quest'ultimo caso.

studio in corso...

RE: Programmazione lato PC - Added by Andrea Belloni almost 4 years ago

non ho studiato bene la cosa (anzi solo superficialmente) comunque qui:
https://github.com/firmata/ConfigurableFirmata/blob/master/src/StepperFirmata.cpp
dopo la riga 135 viene mandato un messaggio quando la sequenza di step è completa

qui
https://github.com/edutec/Snap4Arduino/blob/master/snap/node_modules/firmata/lib/firmata.js
alla riga 329 questo messaggio viene gestito

vedi se può essere utile

ciao

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

sono riuscito a far chiamare la callback

var _exit = 0;
var myCallback = function () { _exit = 1; alert("ciao") };

this.arduino.board.stepperConfig(0, DRV_4WIRE, 64, stepper1_directionPin, stepper1_stepPin, stepper1_motorPin3, stepper1_motorPin4);
this.arduino.board.stepperStep(0, CLOCKWISE, 1000, 4000, myCallback);
var start = new Date().getTime();
while(_exit == 0) {
if (new Date().getTime() - start > 10000)
_exit = 1;
}

ma se eseguo questo codice, purtroppo il while manda al 100% la CPU e la callback riesce ad essere chiamata solo dopo che si esce dal while (per il timeout di emergenza di 10 sec.)
se tolgo il while, la callback è chiamata non appena termina il movimento, quindi il fire della callback funziona, occorre trovare un modo alternativo per il wait/sleep ecc in javascript.

bye

RE: Programmazione lato PC - Added by Andrea Belloni almost 4 years ago

è possibile collegare una variabile javascript con una creata dentro snap con "Make a variable"?

semmai l'attesa si puotrebbe realizzare in snap col blocco "wait until"

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

è quello che stavo provando a fare, ma le variabili sono tutte passate per valore e quindi se la cambi all'interno di un funzione javascript,
poi non esce con il valore modificato :(

RE: Programmazione lato PC - Added by Andrea Cimini almost 4 years ago

sorry... in teoria mi ha funzionato, cioè basta non passare la variabile come parametro di funzione, ma usarla nella funzione direttamente e il cambiamento si ripercuote anche all'esterno, ma sembra che "wait until" non ne vuole sapere di essere true :(

è come se le script variables possano essere usate solo nelle funzioni... e non nei blocchi

non mi funziona neanche il set variable to :(

1 2 (1-25/39)