La oss først finne ut hva som er galt med metoden din. Du prøver å avstemme signalpinnene kontinuerlig og skrive dem ut til serie. Standard seriehastighet er 9600. Hvilket betyr at du kan sende ca. 900 tegn per sekund. Når vi ser på oscillogrammet ditt, kan vi fortelle at signalet du vil analysere har en baseklokke på omtrent 2,5 kHz. Hvilket betyr at du definitivt ikke vil kunne prøve alle nivåendringer med metoden din.
Du kan faktisk bruke loop ()
-funksjonen til å lytte etter endringer, dvs. polle signalet, når du øker den serielle baudhastigheten. Men jeg foreslår at du bruker avbrudd.
Mitt forslag er en tretrinnsprosess.
- få signalet grundig registrert med all relevant informasjon om signalet. Dette inkluderer overføring til PCen din via serielt grensesnitt.
- Analyser signalet offline. dvs. etter å ha mottatt den på PCen din
- Tilpass arduino-koden din for å dekode den videre før du overfører den til PCen
la oss komme til del 1): les Arduino-dokumentasjon om avbrudd avbruddet lar deg forhindre forstyrrelse av de to oppgavene dine (lese inngangene og skrive til seriell) .Hva er den interessante informasjonen? Jeg tror det er bølgeformen (dvs. signalet i beste oppløsning du kan levere). Du kan prøve bølgeformen din med høy hastighet, men det resulterende datavolumet vil overvelde seriell utgang. Heldigvis har signalet ditt noen åpenbare egenskaper. Hvilke er:
- følger noen timing (dvs. en klokke)
- har en begrenset overføringslengde (protokollramme)
- har en begrenset overføringshastighet ( som kan sees fra oscillograf)
Den beste måten å beholde så mye av signalinformasjonen ved å redusere mengden seriell overføring er å registrere tiden for hvert nivåendring.
Oppdateringer: buffer brukt, bufret utgang etter mottak av tidsavbrudd
#define RECVTIMEOUT 2000 // vi tror mer enn 2000 usec er slutt på overføring
#define MAXEVENTS 100 uint8_t inpin = 2; volatile usignert lang tidsstart = 0; uint8_t transmitLevel = LOW; volatile uint8_t state = 0; // liten tilstandsmaskin: 0 = ingenting skjedde ennå, 1 = motta data, 2 = motta timeoutvolatile uint16_t tstamps [MAXEVENTS]; // vi lagrer tidsstempler for mottatte symboler herflyktige uint16_t nivåer [MAXEVENTS]; // vi lagrer nivåer av mottatte symboler herflyktig uint8_t indeks = 0; // vi lagrer dataindeks her. uint8_t count = 0; // teller for senere bruk. flyktig bool-konflikt = falsk; // vil bli satt, hvis overføring er i konflikt med mottaksfunksjonen. unngå pinchange () // ISR (avbryte tjenestes rutine) {switch (state) {case 0: timestart = micros (); t-stempler [indeks] = 0; nivåer [indeks] = digitalRead (inpin); tilstand = 1; ++ indeks; gå i stykker; tilfelle 1: t-stempler [indeks] = mikro () - tidsstart; nivåer [indeks] = digitalRead (inpin); ++ indeks; gå i stykker; tilfelle 2: konflikt = sant; }} ugyldig oppsett () {Serial.begin (115200); // høy seriell rate. ikke glem å sette det samme i IDE attachInterrupt (0, &pinchange, CHANGE); // kontrolleren trenger å vite, hvor ISR-en din er.} ugyldig loop () {switch (state) {case 1: if (index > 20) {if (micros () - timestart > RECVTIMEOUT) {state = 2; }} hvis (indeks > = MAXEVENTS) {state = 2; } gå i stykker; tilfelle 2: for (count = 0; count<index; ++ count) {Serial.print (tstamps [count]); Serial.print (";"); Serial.println (nivåer [count]); } hvis (konflikt) {Serial.println ("for kortere tid til å sende data"); } indeks = 0; konflikt = 0; tilstand = 0; }}
Dette skal gi en fin csv med alle signalkantene dine i mikrosekunder, som du kan lime direkte inn i favoritt regnearkprogrammet. Dette er bare for ett signal. For å analysere begge deler, må du forbedre det tilsvarende.
Oppdater 1
del 2)
fra innhentede data fra vår forrige kodeversjon (kodebit for kortfattethet)
tidssignal tidsforskjell2614592 0 4682615056 1 4642615524 0 4682616496 0 9722616960 1 4642617956 0 9962618960 1 10042620424 1 14642621352 1 9282622324 1 9722623320 0 996
/ p>
- Koden i den første versjonen av svaret fungerte ikke ordentlig. Hver 1 skal følges av et 0 i kolonne 2 og omvendt. Dette stemmer tilsynelatende ikke, noe som fører oss til den konklusjonen at vi savnet noen hendelser.
- tidsforskjeller ser ut til å være multipler på omtrent 470 μs. Vi kan betrakte dette som lengden på et symbol.
Så hva er galt med koden? Jeg brukte noInterrupts () for å stoppe Interrupts for å kopiere dataene. Jeg håpet det vil ikke være nivåendringer i løpet av denne korte tidsperioden, men tilsynelatende var dette ikke sant. Hvordan fikser jeg det? Vi må bedre finne en annen måte å registrere begivenhetene og overføre dem. Jeg anbefaler å holde deg til avbruddsteknikken, men endre måten vi lagrer hendelsene på og leser den opp. La oss bruke en buffer som er stor nok til alle hendelser i en overføring. Etter en overføring kan vi sende all data uten problemer via seriell til PCen.
Hva kan vi forvente? 0 og 1 bør sendes vekselvis, med rimelig tid. Hvis vi kan bevise dette, kan vi endre hovedsløyfen igjen for dekoding av kode 39.
del 3)
- skriv kode som lagrer et ord av kode 39 i en buffer
- en annen kode som dekoder ordet til en byte når bufferen er full
- overfører den byten via seriell
(mange forbedringer mulig).