Pages: 1 [2] 3   Go Down
Author Topic: Problema con la seriale  (Read 2519 times)
0 Members and 1 Guest are viewing this topic.
Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

apire bene i delay e i flussi.
Nel codice di Arduino esiste un flusso principale del programma, ripetuto ininterrottamente. Il loop(). Tutto quello che è lì dentro viene ripetuto continuamente. Questo per scelta dei progettisti, che hanno strutturato un sketch in 2 blocchi distinti, setup() e loop(). Setup() viene eseguito solo 1 volta, il loop() sempre.
Siccome non c'è attesa tra un'istruzione e l'altra, può capitare di avere la necessità di attendere un certo lasso di tempo tra l'esecuzione di un'azione e la successiva. E' stato perciò pensato al delay(), una funzione che attende x millisecondi.
Il tutto però sempre inserito nel loop().

Quote
Anzi se qualcuno sa darmi consigli per capire flusso, delay e problematiche legate a questo. Ad esempio se chiamo una funzione nel loop, è sincrona o asincrona?
Cosa intendi per sincrono/asincrono?
Se intendi eseguito nel flusso principale, tutto quello che è scritto in linguaggio Arduino è sincrono. Ma sarebbe più corretto dire "seriale". Una istruzione dietro l'altra, ecco come viene eseguito il codice Arduino.
Se hai un loop() così strutturato:
loop() {
  funzione1();
  funzione2();
}
funzione2 sarà eseguito sempre e soltanto dopo funzione1. Dopo funzione2 sarà sempre eseguita funziona1 perché loop() è ciclico.

Quote
Esiste qualcosa di asincrono a parte gli interrupt?
Ad esser sinceri a livello di SW non esiste nulla di asincrono, ossia eseguito alternativamente a qualcos'altro. Questo perché l'Atmega non è dotato di multitasking per cui anche per eseguire un interrupt viene bloccata l'esecuzione del codice principale. Il micro infatti salva lo stato dei registri, esegue la routine di interrupt, e poi torna ad eseguire il programma dell'utente dal punto in cui era stato interrotto.
A livello di HW esiste un modulo asincrono, il timer 2, che può funzionare con una sorgente di clock differente da quella del clock di sistema, lavorando quindi anche a frequenze differenti ed anche quando il micro è in sleep. Ma non penso c'entri molto con quello che volevi sapere.

Quote
Gli interrupt interrompono anche un delay? La seriale continua a bufferizzare tranquillamente anche se sono in un delay vero?
Gli interrupt bloccano anche un delay. La funzione delay altro non fa che controllare che il contatore interno dei millisecondi (agganciato al timer 0 e letto tramite la funzione millis()) sia avanzato del valore passato come parametro, ossia sia trascorso il tempo richiesto. Ma per far ciò è interrotta continuamente dall'interrupt che incrementa il contatore del timer 0, nonché da altri interrupt. Un altro interrupt è proprio quello che gestisce i dati in arrivo sulla seriale ed in partenza su di essa. Tutte operazioni eseguite in background, quindi ad un livello inferiore rispetto a quello del codice utente. Ma io non mi azzarderei a definire un interrupt un'operazione asincrona perché, come detto, in realtà interrompi l'esecuzione dello sketch e poi la riprendi in un secondo tempo.

Quote
Chi mi sa dare consigli di dove trovare documentazione ben fatta su questa problematica con esempi?
Grazie
Cerca su internet, leggi un sacco su timer, interrupt, guarda il datasheet e sperimenta.
Logged


Camisano Vicentino (VI), Italy
Offline Offline
God Member
*****
Karma: 5
Posts: 956
ƎR like no other.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

ottimo direi, grazie per i chiarimenti! smiley-wink
Logged

Riccardo Ertolupi of the Vicenza Thunders Team: http://www.VicenzaThunders.com

Milan
Offline Offline
Sr. Member
****
Karma: 0
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oggi sono nel mondo win32 e DB quindi niente Arduino, ma lunedì faccio un po' di prove.

Che l'interrupt interrompe un delay lo avevo provato ieri. Quindi ne ho la certezza fisica.

Quote
Cosa intendi per sincrono/asincrono?
Detto che è chiaro che essendoci un processore (oggi diremmo single core) parallelismi reali sono impossibili.
Per asincrono intendevo qualcosa tipo multithread. O flusso principale e gestione di eventi che interrompono il flusso.
Tipo funzione1 fa qualcosa in attesa di ma funzione2 viene eseguita proprio perchè funzione1 non porta via CPU.
MA dalla tua risposta ho gia capito, non ci sono meccanismio che lo facciano, devi essere tu che fai funzione uno che se non è successo qualcosa...finisca e al limite venga riattivata al prossimo loop.

Leo, anche se faccio un interrupt, la seriale ha un buffer e continua a leggere dati o smette e perde glie eventuali dati?

Altra cosa, se sto eseguendo un SerialEvent, è so solleva un interrupt... viene caricata la routine di interrupt o serialevent ha la priorità?
Ci sono tabelle di priorità?
Col MEGA ho 4 interrupt, c'è una logica di importanza (tipo nei xx86 che avevano un codice di importanza da 0 a 8 e uno di livello inferiore non poteva interrompere uno superiore) o qualunque può interrompere qualunque?

E' solo per capire tutto meglio, per la mia applicazione ho già tutto quello che mi serve.
Ciao




Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Detto che è chiaro che essendoci un processore (oggi diremmo single core) parallelismi reali sono impossibili.
Per asincrono intendevo qualcosa tipo multithread. O flusso principale e gestione di eventi che interrompono il flusso.
Tipo funzione1 fa qualcosa in attesa di ma funzione2 viene eseguita proprio perchè funzione1 non porta via CPU.
MA dalla tua risposta ho gia capito, non ci sono meccanismio che lo facciano, devi essere tu che fai funzione uno che se non è successo qualcosa...finisca e al limite venga riattivata al prossimo loop.
Esatto. Devi gestire tutto via software. E' ciò che fanno gli RTOS, i SO in tempo reale: assegnano dei tick ad ogni task, terminato il tempo a disposizione congelano il task salvando lo stato di tutti i registri e poi caricano i registri salvati del task successivo. Ma anche qui c'è un interrupt agganciato ad un timer a gestire i vari tick.

Quote
Leo, anche se faccio un interrupt, la seriale ha un buffer e continua a leggere dati o smette e perde glie eventuali dati?
Nel micro ci sono diversi interrupt, ognuno con una certa priorità sugli altri. Inoltre per default tutte le ISR sono compilate atomicamente (vale a dire che viene creato un codice non interrompibile da un'altra ISR) per cui se il micro sta eseguendo una ISR ed arriva qualcosa sulla seriale, l'evento viene registrato ma il relativo interrupt non viene eseguito finché non è terminata l'altra ISR. Terminata questa, viene eseguita l'ISR per gestire l'arrivo dei dati sulla seriale, che vengono riversati nel buffer.

Quote
Altra cosa, se sto eseguendo un SerialEvent, è so solleva un interrupt... viene caricata la routine di interrupt o serialevent ha la priorità?
Ci sono tabelle di priorità?
Sì, come ti ho detto ci sono delle priorità. Vedi il datasheet del 328 alla pag. 67, cap. 12.4.

Quote
Col MEGA ho 4 interrupt, c'è una logica di importanza (tipo nei xx86 che avevano un codice di importanza da 0 a 8 e uno di livello inferiore non poteva interrompere uno superiore) o qualunque può interrompere qualunque?
Diciamo che hai 4 interrupt esterni, non è corretto dire che hai 4 interrupt e basta  smiley-wink
Anche in questo caso ci sono delle priorità: INT0 verrà eseguito prima di INT1, INT1 prima di INT2 ecc...
Logged


Milan
Offline Offline
Sr. Member
****
Karma: 0
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Parli di questo documento?
http://www.atmel.com/Images/doc8161.pdf

Qui direi che parte da pagina 67.

Oppure dimmi tu il link del pdf di cui parli.
Grazie
Nic
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Parli di questo documento?
http://www.atmel.com/Images/doc8161.pdf

Qui direi che parte da pagina 67.

Oppure dimmi tu il link del pdf di cui parli.
Grazie
Nic
Pag. 65. Sì, ma il tuo datasheet è del 2009. Qui c'è l'ultima versione, presa or ora dal sito Atmel:
http://www.atmel.com/Images/doc8271.pdf
Logged


Milan
Offline Offline
Sr. Member
****
Karma: 0
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi sembrava un po' ingiallito.
Grazie
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mi sembrava un po' ingiallito.
Grazie
ROTFL  smiley-lol
Logged


Milan
Offline Offline
Sr. Member
****
Karma: 0
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ecco adesso vi chiedo aiuto con questo esempio.
Code:
#include <Adafruit_VC0706.h>
#include <SoftwareSerial.h>   
Adafruit_VC0706 cam = Adafruit_VC0706(&Serial1);

int32_t time = millis();

void setup() {
  Serial.begin(38400);
  delay(1000);
  time = millis();
  Serial.print(time); Serial.println(" start");
  Serial.println("UNO");
 
  if (cam.begin()) {
    Serial.println(F("OK CAM"));
  } else {
    Serial.println("NO CAM");
  }
  time = millis() - time;
  Serial.print(time); Serial.println(" ms elapsed");
  Serial.println("DUE");
}

void loop() {

if (Serial.available())
  Serial1.write(Serial.read());

if (Serial1.available())
  Serial.write(Serial1.read());
  }

E questo è l'output.
Quote
999 start
UNO
OK CAM
14 ms elapsed
DUE
VC0703 1.00
Ctrl infr exist
User-defined sensor
625
Init end

Non mi spiego perchè ho del testo scritto dopo il "DUE" che è l'ultima istruzione.
Grazie



Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Vedendo che ciò che è stato scritto (VC0703 1.00) è simile al nome della libreria che usi (Adafruit_VC0706.h) e che istanzi proprio sulla seriale 1 (Adafruit_VC0706 cam = Adafruit_VC0706(&Serial1)smiley-wink, mi viene da pensare che sia o un messaggio della lib o qualcosa che può spedire la cam una volta aperta la connessione.
Logged


Milan
Offline Offline
Sr. Member
****
Karma: 0
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Anche io penso a questo, ma perchè mi arriva dopo?
Cosa posso fare per farlo arrivare prima di tutto?
N
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 327
Posts: 22640
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Studia la libreria.
Se la libreria non scrive nulla, allora è la cam. Potresti intercettare la prima stringa spedita e ignorarla semplicemente.
Logged


Lamezia Terme
Offline Offline
Shannon Member
****
Karma: 564
Posts: 12450
Le domande di chi vuol imparare rappresentano la sua sete di sapere
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quell'Init end mi fa pensare ad una procedura di inizializzazione della Webcam, come dice Leo basta intercettare la trasmissione dei dati e non visualizzarli, anche se forse quel valore 625 ha un suo significato che potrebbe tornare utile
Logged

Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Milan
Offline Offline
Sr. Member
****
Karma: 0
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Scusate non mi sono spiegato.
Non mi da fastidio e già la uso senza problemi, volevo solo capire le tempistiche e cosa succede.
Sempre per il discorso del flusso.
Avevamo detto che tutto segue il flusso, vorrei capire qual'è a vostro avviso l'istruzione del mio programma che scatena quella risposta.

Io penserei <<cam.begin()>>, ma a questo punto mi chiedo perchè arriva cosi tanto dopo.

N

Logged

Milan
Offline Offline
Sr. Member
****
Karma: 0
Posts: 375
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
const uint8_t hexZero = 0x00;
void setup(){
  Serial.begin(38400);
  Serial1.begin(38400);
  delay(1000);
  Serial1.write(0x56);
  Serial1.write(hexZero);
  Serial1.write(0x26);
  Serial1.write(hexZero);
}
void loop() {
if (Serial1.available())
  Serial.write(Serial1.read());
}

Ottengo
Quote
0x760x000x260x00VC0703 1.00
Ctrl infr exist
User-defined sensor
625
Init end

I primi 4 li ho messi io in esadecimali, erano caratteri non stampabili.
N


Logged

Pages: 1 [2] 3   Go Up
Jump to: