Baserade Arduino tidshändelse logger
Exempel källkod för en Arduino baserad tidshändelse datalogger. Visar avbrott, asynkrona loggning och kontakt de studsa. Avsedda för en hjul-läges brytare, loggar som växel är förlovad.
Vi använder en reed switch som studsar både engagerade och när dis engagerade. Detta kastar flera avbrott. Ring buffert input kontroller om tidsperioden händelsen är vida kortare än tidigare loggade tidshändelse. I så fall avvisas kort trigger som kontakt bounce. Avvisade händelser lagras och om många avvisar inträffar i rad, de är alla inloggade, förutsatt att något hände och de kan vara viktiga händelser. Motivationen är att det är bättre att logga några studsar än att missa en händelse för det här programmet. Data längre kan saneras vid efterbehandlingen, men vi vill inte att våra loggar med alla händelser kontakta bounce-röran.
/*
$URL: svn + ssh://aaron $
$Id: vLogger.ino 62 2012-06-03 20:11:13Z aaron $
Logga in de tider när ett hjul lägesgivare utlöser,
som en indirekt metod för loggning tid och avstånd,
som kan användas för att beräkna hastighet och acceleration
i ett kust-ner vind motstånd experiment.
Användaren och vänder switch att spela in på en ring buffert.
Huvudloop skriver ut ringen buffert innehållet till serieport, asynch.
Varje gång de post operation cyklerna, återställs tiden till
börja på noll.
Sensor switch måste vara på pin 2, eftersom detta stift använder
standard yttre mellanjobb 0
*/
#define PIN_RECORD 4 / / spela in på/av-knapp
#define PIN_LED_RECORD 8 / / på när inspelning
#define PIN_LED_SENSOR 13 / / växlar som sensorn visar
#define BUF_LEN 256 / / prover i databufferten ring
#define MAX_SHORT 10 / / max "korta" händelser innan förutsatt att de inte är kontakta bounce
TypeDef lång DATATYP;
#include / / sprintf
Diagnostiska produktionen logger. Samtalsloggen från ISR, skriva ut utanför ISR
#define MAX_LOG_LEN 40
#define LOG_BUF_LEN 8
klass Logger {
skyddad:
flyktiga int nIn;
int nOut;
char buf [LOG_BUF_LEN] [MAX_LOG_LEN];
offentlig:
char msgBuf [MAX_LOG_LEN];
Logger() {nIn = nOut = 0;}
void print()
{
om (nOut > = nIn) återvända;
int jag = nOut % LOG_BUF_LEN;
nOut ++;
Serial.println(BUF[i]); Serial.flush();
}
Tom log (const char * msg)
{
int i, k;
k = nIn % LOG_BUF_LEN;
för (jag = 0; (msg[i]!=0) & & (jag < MAX_LOG_LEN-1); i ++) buf [k] [i] = msg [i];
BUF [k] [i] = 0;
nIn ++;
}
void log() {log(msgBuf);} / / för att använda som msgBuf
} Loggen;
klass RingBuffer {
skyddad:
flyktiga int nIn;
int nOut;
flyktiga DATATYPE buf [BUF_LEN];
offentlig:
void reset() {nIn = nOut = 0;}
RingBuffer() {reset();}
flyktiga void push(DATATYPE x)
{
om (nOut < = nIn - BUF_LEN)
{
sprintf (Log.msgBuf,"RingBuffer Overflow %d", x); Log.log();
Serial.println ("RingBuffer Overflow"); Serial.println(x);//Serial.flush();
hemkomst.
}
int jag = nIn % BUF_LEN;
BUF [i] = x;
nIn ++;
}
inline bool empty() const {return (nOut > = nIn);}
DATATYPEN pop()
{
om (nOut > = nIn) return(0xffff);
int jag = nOut % BUF_LEN;
nOut ++;
Return(BUF[i]);
}
DATATYPEN peek() / / kika på sista utgång
{
int jag = nOut % BUF_LEN;
Return(BUF[i]);
}
DATATYPEN kika (const int nBack) / / topp vid angivna prev INPUT, 0 är de senaste
{
int jag = nIn-1-nBack;
om (jag < 0) return 0;
Return(BUF[i]);
}
inline int nPush() const {return(nIn);}
inline int nPop() const {return(nOut);}
inline int depth() const {return(nIn-nOut);}
inline int maxDepth() const {return(BUF_LEN);}
};
klass TimeEventRingBuffer: offentliga RingBuffer {
skyddad:
osignerade långa t0;
flyktiga int nShort;
flyktiga DATATYP shortBuf [MAX_SHORT];
offentlig:
void reset()
{
setZero();
nShort = 0;
RingBuffer::reset();
}
TimeEventRingBuffer()
{
nShort = t0 = 0;
}
void push()
{
osignerade långa tt = millis();
DATATYPEN tNow = (DATATYPE)(tt-t0);
Sök efter kontakt bounce
DATATYPEN t1 = peek(0); föregående inspelade input
DATATYPEN t2 = peek(1);
om (tNow-t1 < 0,1 * (t1-t2))
{/ / kort trigger, sannolikt kontakta bounce
om (nShort < MAX_SHORT)
{
shortBuf [nShort ++] = tNow;
hemkomst.
}
För många kort utlösare i rad, dumpa dem
för (int jag = 0; jag < MAX_SHORT; i ++) RingBuffer::push(shortBuf[i]);
}
spela in tidpunkten för denna händelse
RingBuffer::push(tNow);
nShort = 0; denna händelse var bra. Återställ räknaren för kort-trigger
}
void setZero()
{
t0 = millis();
}
};
TimeEventRingBuffer Data.
bool RecordingOn;
ISR när hjulet sensor händelse upptäcks
void wheelSense()
{
om (RecordingOn)
{
Data.push();
}
digitalWrite(PIN_LED_SENSOR,digitalRead(PIN_LED_SENSOR)? LOW:HIGH);
}
void setup()
{
pinMode(2,INPUT); hårdkodad till stift 2, sedan använda standard ext. avbryta 0
pinMode(PIN_RECORD,INPUT);
digitalWrite(PIN_RECORD,HIGH); Aktivera pull-up resistor
digitalWrite(2,HIGH);
pinMode (PIN_LED_RECORD, OUTPUT);
pinMode (PIN_LED_SENSOR, OUTPUT);
digitalWrite(PIN_LED_RECORD,HIGH);
digitalWrite(PIN_LED_SENSOR,HIGH);
RecordingOn = true; //false;
attachInterrupt(0,wheelSense,RISING); INT0 är på stift 2 (INT1 på stift 3)
Serial.BEGIN(9600); kanske vill en annan seriell bildskärm, som kan vara snabbare
}
void loop()
{
Log.Print(); Kontrollera om några loggmeddelanden behöver skrivas ut
IF (!. Data.Empty())
{
Serial.Print(data.nPop());
Serial.Print("\t");
Serial.println(data.pop());
Serial.flush();
}
Kontrollera om inspelningen är aktiverat
bool rec = (digitalRead (PIN_RECORD) == låg)? sant: falskt;
REC = sant; / / alltid rekord för testning
om (RecordingOn)
{
om (! rec)
{/ / slå inspelning OFF
digitalWrite(PIN_LED_RECORD,LOW);
RecordingOn = false;
Delay(2); undvika kontakt bounce
}
}
annat
{/ / inspelning är off
om (rec)
{/ / övergång från av till på, börja spela in
digitalWrite(PIN_LED_RECORD,HIGH);
Data.setZero();
om (Data.empty()) Data.reset();
RecordingOn = sant;
Delay(2); undvika kontakt bounce
}
}
}
Här är ett bekvämt LINUX skript att både Visa och logga data från en seriell anslutning. Denna kod är inställt för en-USB/seriell portanslutning, men om du ändrar enheten det ser till något liknande /dev/rfcomm0 det kan ställas in att arbeta över en Bluetooth/SPP enhet.
#! / usr/bin/perl - w
# Loggar ut från en arduino typiska 9600 8-n-1
# antar de flesta nyligen skapade tty är Arduino.
# för de flesta användare, bör detta vanligtvis arbete
$devName = ' ls -t/dev/tty * | huvud 1 ";
Chomp($devName);
skriva ut "Lyssna på $devName\n";
# Ställ in port för vanliga Arduino (SerialMonitor-liknande) inställningar
system ("stty -F $devName cs8 9600 ignbrk - brkint - icrnl - imaxbel - opost - onlcr - isig - icanon - iexten-eko - echoe - echok - echoctl - echoke noflsh - ixon - crtscts");
$logFileName = ($#ARGV > = 0)? $ARGV [0]: "/ tmp/serial.log";
skriva ut "Loggning till $logFileName\n";
$pid = fork();
om ($pid == 0)
{
# Detta är barnet.
lokala $cmd = "svans -f $devName > $logFileName";
# av någon anledning, ovan fungerade inte på en netbook, men det gjorde:
#local $cmd = "cat $devName > $logFileName";
skriva ut "$cmd\n";
exec($CMD);
}
annat
{
# Detta är överordnad, Visa logg.
# förhoppningsvis när är ^ C'ed eller dödades, det kommer att döda barn också
sova 2.
lokala $cmd = "svans -f $logFileName";
skriva ut "$cmd\n";
exec($CMD);
}