Un amico usa normalmente per acquisizione delle schede Terra ACME ed sostanzialmente mi ha lanciato una sfida se fosse piu' performante nel calcolo puro la sua Terra o la mia YUN
Il terreno di battaglia e' stato scelto con l'elaborazione dello script in Python per la creazione di un insieme di Mandelbrot
Lo script nel dettaglio e' il seguente
--------------------------------------------------
from PIL import Image
from PIL import ImageDraw
# drawing area
xa = -2.0
xb = 1.0
ya = -1.5
yb = 1.5
maxIt = 255 # max iterations allowed
# image size
imgx = 512
imgy = 512
image = Image.new("RGB", (imgx, imgy))
for y in range(imgy):
zy = y * (yb - ya) / (imgy - 1) + ya
for x in range(imgx):
zx = x * (xb - xa) / (imgx - 1) + xa
z = zx + zy * 1j
c = z
for i in range(maxIt):
if abs(z) > 2.0: break
z = z * z + c
image.putpixel((x, y), (i % 4 * 64, i % 8 * 32, i % 16 * 16))
image.save("mandel.bmp", "BMP")
--------------------------------------------------
Su Arduino Yun e' stato necessario installare il pacchetto python-imaging-library.
Su Terra si e' presentato un problema inatteso. I repository di EmDebian (Embedded Debian) non sono piu' disponibili per cui il programma e' stato fatto girare eliminando i riferimenti alle librerie grafiche (dando quindi un piccolo vantaggio a Terra)
Alla fine il risultato e' stato meno definitivo di quanto creduto
Terra ha impiegato 11 minuti e 35 secondi contro i 14 minuti e 52 secondi di Yun (per confronto un MacBook i5 impiega 6.1 secondi)....considerando che Arduino Yun costa circa 62 Euro in confronto ai 199 euro di Terra Kit la mia scelta e' piu' orientata verso la Yun (con circa 200 euro si iniziano a comprare dei portatili completi come i ChromeBook)
lunedì 12 gennaio 2015
SismoArduino (142Hz)
Riprendendo il progetto di SismoArduino ho voluto anche qui provare a migliorare le prestazioni del passo di campionamenti
Le modifiche hanno riguardato sostanzialmente la riduzione dei tempi di ritardo tra le letture e l'uso di un pc piu' perfomante rispetto a quello usato in precedenza
Con queste modifiche il passo di campionamento e' salito ad 1 campione ogni 7 millisecondi in linea con quanto provato con SismoYUN (a questo punto questo puo' essere il limite della scheda senza entrare in modalita' free running)
----------------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
//Arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,2);
unsigned int localPort = 8888;
//Server
byte remoteIP[4] = {192,168,1,1};
int remotePort = 5005;
String dati;
char charBuf[1024];
EthernetUDP Udp;
void setup() {
Serial.begin(115200);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
}
void loop() {
int x = analogRead(A5);
delay(2);
int y = analogRead(A4);
delay(2);
int z = analogRead(A3);
dati = String(x)+","+String(y)+","+String(z);
Serial.println(dati);
dati.toCharArray(charBuf, 1024);
Udp.beginPacket(remoteIP, remotePort);
Udp.write(charBuf);
Udp.endPacket();
delay(2);
}
----------------------------------------------------
Le modifiche hanno riguardato sostanzialmente la riduzione dei tempi di ritardo tra le letture e l'uso di un pc piu' perfomante rispetto a quello usato in precedenza
Con queste modifiche il passo di campionamento e' salito ad 1 campione ogni 7 millisecondi in linea con quanto provato con SismoYUN (a questo punto questo puo' essere il limite della scheda senza entrare in modalita' free running)
----------------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
//Arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,2);
unsigned int localPort = 8888;
//Server
byte remoteIP[4] = {192,168,1,1};
int remotePort = 5005;
String dati;
char charBuf[1024];
EthernetUDP Udp;
void setup() {
Serial.begin(115200);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
}
void loop() {
int x = analogRead(A5);
delay(2);
int y = analogRead(A4);
delay(2);
int z = analogRead(A3);
dati = String(x)+","+String(y)+","+String(z);
Serial.println(dati);
dati.toCharArray(charBuf, 1024);
Udp.beginPacket(remoteIP, remotePort);
Udp.write(charBuf);
Udp.endPacket();
delay(2);
}
----------------------------------------------------
venerdì 9 gennaio 2015
Recuperare il controllo di Arduino YUN con YunSerialTerminal
Usando YUN (almeno a me capita un po' troppo spesso) puo' succedere di perdere il controllo della porzione Linux che non risulta piu' raggiungibile via rete. Il factory reset ottenuto tramite la pressione per 30 secondi del tasto WLAN RST non mi ha mai funzionato
Un modo per correggere gli errori e ripristinare la rete (wifi od ethernet che sia) e' quello di connettere la YUN fisicamente con il cavo USB e montare lo sketch presente in Esempi/Bridge/YunSerialTerminal
A questo punto si apre il terminale seriale e si preme il pulsante di YUN RST (a fianco delle porte analogiche). Sul terminale seriale si vedranno scorrere i messaggi del boot Linux fino a conquistare una shell con cui poter interagire e rimettere a posto il lato software della scheda
Un modo per correggere gli errori e ripristinare la rete (wifi od ethernet che sia) e' quello di connettere la YUN fisicamente con il cavo USB e montare lo sketch presente in Esempi/Bridge/YunSerialTerminal
A questo punto si apre il terminale seriale e si preme il pulsante di YUN RST (a fianco delle porte analogiche). Sul terminale seriale si vedranno scorrere i messaggi del boot Linux fino a conquistare una shell con cui poter interagire e rimettere a posto il lato software della scheda
Arduino UDP Broadcast (SismoArduino)
Questa e' una piccola modifica al sistema di invio dati di SismoArduino
In alcuni casi puo' essere comodo non conoscere a priori l'indirizzo del server a cui inviare i dati ed essere comunque in grado di configurare la scheda Arduino
La soluzione e' quella di inviare i pacchetti UDP in modalita' broadcast. In questo modo tutte le macchine della rete ricevono il pacchetto; cio' genera ovviamente un traffico inutile sulla rete ma e' piu' o meno quello che fanno i computer Windows e nessuno si e' mai lamentato piu' di tanto per cui non mi farei problemi
Lo sketch di invio deve solo modificare l'indirizzo del server con l'IP di broadcast che e' 255.255.255.255 (la versione 192.168.1.255 non funziona!!)
-------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
//Arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,2);
unsigned int localPort = 8888;
//Server
byte remoteIP[4] = {255,255,255,255};
int remotePort = 5005;
String dati;
char charBuf[1024];
EthernetUDP Udp;
void setup() {
Serial.begin(115200);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
}
void loop() {
int x = analogRead(A5);
delay(2);
int y = analogRead(A4);
delay(2);
int z = analogRead(A3);
dati = String(x)+","+String(y)+","+String(z);
Serial.println(dati);
dati.toCharArray(charBuf, 1024);
Udp.beginPacket(remoteIP, remotePort);
Udp.write(charBuf);
Udp.endPacket();
delay(2);
}
-------------------------------------------
In alcuni casi puo' essere comodo non conoscere a priori l'indirizzo del server a cui inviare i dati ed essere comunque in grado di configurare la scheda Arduino
La soluzione e' quella di inviare i pacchetti UDP in modalita' broadcast. In questo modo tutte le macchine della rete ricevono il pacchetto; cio' genera ovviamente un traffico inutile sulla rete ma e' piu' o meno quello che fanno i computer Windows e nessuno si e' mai lamentato piu' di tanto per cui non mi farei problemi
Fonte Wikipedia |
Lo sketch di invio deve solo modificare l'indirizzo del server con l'IP di broadcast che e' 255.255.255.255 (la versione 192.168.1.255 non funziona!!)
-------------------------------------------
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
//Arduino
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,2);
unsigned int localPort = 8888;
//Server
byte remoteIP[4] = {255,255,255,255};
int remotePort = 5005;
String dati;
char charBuf[1024];
EthernetUDP Udp;
void setup() {
Serial.begin(115200);
Ethernet.begin(mac,ip);
Udp.begin(localPort);
}
void loop() {
int x = analogRead(A5);
delay(2);
int y = analogRead(A4);
delay(2);
int z = analogRead(A3);
dati = String(x)+","+String(y)+","+String(z);
Serial.println(dati);
dati.toCharArray(charBuf, 1024);
Udp.beginPacket(remoteIP, remotePort);
Udp.write(charBuf);
Udp.endPacket();
delay(2);
}
-------------------------------------------
il programma in Python che funziona da server deve essere invece riscritto per non ignorare i pacchetti broadcast
-------------------------------------------
import socket,select
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST,1)
sock.bind(('',5005))
while True:
msg,add = sock.recvfrom(1024)
print msg
import socket,select
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST,1)
sock.bind(('',5005))
while True:
msg,add = sock.recvfrom(1024)
print msg
-------------------------------------------
giovedì 8 gennaio 2015
SismoYUN (142Hz)
Per spingere ancora piu' al limite il passo di campionamento di Sismo YUN ho modificato lo sketch per ridurre al minimo di tempi tra le letture analogiche
Lo sketch e' il seguente (il ritardo e' passato da 10 millisecondi a 2 millisecondi). Tutta la rimanente configurazione e' la stessa dei precedenti post
------------------------------------------------
void setup() {
delay(50000);
Serial1.begin(115200);
}
void loop() {
Serial1.print(millis());
Serial1.print(",");
Serial1.print(analogRead(A3));
Serial1.print(",");
delay(2);
Serial1.print(analogRead(A4));
Serial1.print(",");
delay(2);
Serial1.println(analogRead(A5));
delay(2);
}
------------------------------------------------
Con questo sistema la media e' stata di una acquisizione ogni 8 millisecondi (circa 142 Hz)
Si osserva chiaramente il miglioramento della forma d'onda rispetto alle acquisizioni a passi di campionamento piu' lenti
Lo sketch e' il seguente (il ritardo e' passato da 10 millisecondi a 2 millisecondi). Tutta la rimanente configurazione e' la stessa dei precedenti post
------------------------------------------------
void setup() {
delay(50000);
Serial1.begin(115200);
}
void loop() {
Serial1.print(millis());
Serial1.print(",");
Serial1.print(analogRead(A3));
Serial1.print(",");
delay(2);
Serial1.print(analogRead(A4));
Serial1.print(",");
delay(2);
Serial1.println(analogRead(A5));
delay(2);
}
------------------------------------------------
Con questo sistema la media e' stata di una acquisizione ogni 8 millisecondi (circa 142 Hz)
Si osserva chiaramente il miglioramento della forma d'onda rispetto alle acquisizioni a passi di campionamento piu' lenti
YUN e Memoria USB
Piu' studio Arduino Yun piu' mi diverto. E' possibile anche attaccardi pennette USB per aumentare lo spazio disco oltre a quello fornito dalla SDCard
per farlo si deve pero' installare il pacchetto kmod-usb2
opkg update
opkg install kmod-usb2
insmod ehci-hcd
se presente /dev/sda1 e' occupato dalla SDCard
per montare la chiavetta usb si monta /dev/sdb1
mount /dev/sdb1 /mnt/usbkey
se presente /dev/sda1 e' occupato dalla SDCard
per montare la chiavetta usb si monta /dev/sdb1
mount /dev/sdb1 /mnt/usbkey
mercoledì 7 gennaio 2015
SismoYUN (30 Hz)
Non contento del passo di campionamento ottenuto nel precedente post ho provato a migliorare le prestazioni svincolandomi dalla libreria Bridge
Il suggerimento mi e' venuto leggendo questo post. In pratica Linux puo' leggere i dati di Arduino, Arduino li puo' spedire sulla Serial1 e Linux li puo' leggere su /dev/ttyATH0.
Per fare cio' si deve pero' modificare il file /etc/inittab commentando la linea che setta questa porta seriale e riavviando
questo e' lo sketch Arduino
e' fondamentale la riga in giallo. Se Arduino inizi a sparare dati sulla seriale a Linux mentre questo e' in fase di boot, il boot stesso si blocca in modo irrecuperabile (limite di 50 secondi prima di iniziare ad inviare dati)!!!!
--------------------------------------------
void setup() {
delay(50000);
Serial1.begin(115200);
}
void loop() {
Serial1.print(millis());
Serial1.print(",");
Serial1.print(analogRead(A3));
Serial1.print(",");
delay(10);
Serial1.print(analogRead(A4));
Serial1.print(",");
delay(10);
Serial1.println(analogRead(A5));
delay(10);
}
--------------------------------------------
SismoYUN in questo caso alimentata da un comune PowerBank da 1000 mA |
Il suggerimento mi e' venuto leggendo questo post. In pratica Linux puo' leggere i dati di Arduino, Arduino li puo' spedire sulla Serial1 e Linux li puo' leggere su /dev/ttyATH0.
Per fare cio' si deve pero' modificare il file /etc/inittab commentando la linea che setta questa porta seriale e riavviando
questo e' lo sketch Arduino
e' fondamentale la riga in giallo. Se Arduino inizi a sparare dati sulla seriale a Linux mentre questo e' in fase di boot, il boot stesso si blocca in modo irrecuperabile (limite di 50 secondi prima di iniziare ad inviare dati)!!!!
--------------------------------------------
void setup() {
delay(50000);
Serial1.begin(115200);
}
void loop() {
Serial1.print(millis());
Serial1.print(",");
Serial1.print(analogRead(A3));
Serial1.print(",");
delay(10);
Serial1.print(analogRead(A4));
Serial1.print(",");
delay(10);
Serial1.println(analogRead(A5));
delay(10);
}
--------------------------------------------
per la parte Linux i dati sulla seriale li ho letti con Python. Per fare cio' ho usato la libreria Python Serial che non e' disponibile mediante opkg ma deve essere installata manualmente con il setup normale di Python
i dati passati sono il tempo in millisecondi e poi i tre valori di accelerazione. Questi vengono salvati sulla sdcard
--------------------------------------------
#!/usr/bin/python
import serial
ser = serial.Serial('/dev/ttyATH0',115200)
out_file = open("/mnt/sda1/dati_veloci.txt","w")
while True:
lettura = ser.readline()
out_file.write(lettura)
--------------------------------------------
Con queste impostazioni i dati vengono registrati e salvati alla velocita' di circa 30 Hz. Forse passando ad una SdCard di classe 10 (o piu' veloci) le cose possono ancora migliorare ma gia' cosi' il miglioramento e' significativo
Per la presentazione dei dati a Web e' stato utilizzato il sistema precedente modificando leggermente gli script
Con queste impostazioni i dati vengono registrati e salvati alla velocita' di circa 30 Hz. Forse passando ad una SdCard di classe 10 (o piu' veloci) le cose possono ancora migliorare ma gia' cosi' il miglioramento e' significativo
Per la presentazione dei dati a Web e' stato utilizzato il sistema precedente modificando leggermente gli script
Iscriviti a:
Post (Atom)
Change Detection with structural similarity
L'idea di base e' quella di cercare le differenze tra le due immagini sottostanti Non e' immediatamente visibile ma ci sono dei ...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...