/* start of code to capture, some day poll Neptune water meter data 9/6/12 jw this one generates clocks */ #define sp Serial.print #define spl Serial.println #define sps Serial.print(" ") // where Neptune is connected #define CLKPIN 2 #define DATPIN 3 // wait this long for data to settle after an edge #define MIDCLOCK 30 #define LO 0 #define HI 1 #define ERR 2 #define FRAME 16 #define WAIT 15 // amount of memory to allocate to store a polling run #define MAXFRAMES 100 // max number of clock half-cycles to generate #define MAXCLKS 1600 // half-cycle time of clock #define CLKUS 150 // I added a little inverting buffer in front of the data // line. Set INVERTDATA to 0 if Neptune data line straight in #define INVERTDATA 1 int bits[MAXFRAMES]; // store frame being received here int frame=0; // counts number of frames received byte errcnt[MAXFRAMES],frameerr[MAXFRAMES]; // counts 2 kinds of errors byte gotdata=0; // if true, we have data to dump long start=-10000; long his=0,los=0; // some debug stuff int stores=0; // more debug stuff int getbits=0; // more debug void setup(){ Serial.begin(115200); // clear data and counters for(int i=0;i 1000){ start=millis(); Serial.print(msec); Serial.println(" since last"); }// end time check // main get-in-sync loop while(getbit()!=FRAME); state=0; // first bit }// end if WAIT abit=getbit(); //actual read a bit( if(abit==0){los++;} if(abit==1){his++;} if(abit==ERR){ errcnt[frame]++; state=WAIT; // can't print and keep up at same time! //sp("errs ");spl(errcnt[frame],DEC); goto TOP; }// end if ERR if(abit==FRAME){ // we shouldn't see a frame here frameerr[frame]++; state=WAIT; //sp("frame errs ");spl(frameerr[frame],DEC); goto TOP; }// end if FRAME //OK - store it //sp("storing ");spl(abit,DEC); stores++; // LSB first if(abit){bits[frame]|=(1<=15){ frame++; gotdata=1; state=WAIT; }// end if got 15 bits goto TOP; }// end loop // ****** WAIT FOR A CLOCK EDGE ******* // now generates clocks // returns new clock state // waits so next read of data pin will be good int wait4edge(){ static int curr=0,clkcnt=0; int i,secs; // this generates clocks #if 1 if(clkcnt++ > MAXCLKS){ // note - counting half-clocks digitalWrite(CLKPIN,0); // make sure we leave clock low spl("clocks done"); dumpdata(); delay(1000000); }// end count check // wait clock half-period delayMicroseconds(CLKUS); if(curr==0){ digitalWrite(CLKPIN,1); curr=1; }// end if 0 else{ digitalWrite(CLKPIN,0); curr=0; }// end else #endif // Original code is lost, but this probably // *reads* clocks. If you want to do this, be // sure to comment out pinMode(CLKPIN,OUT) in setup() // (as well as #if'ing out clock generating code above). // This also doesn't include a call to dumpdata, so // you'll have to invent your own. // A little debounce code might be nice as well. // Sorry, after I could generate my own clocks I // never looked back. #if 0 // wait for clock to change while(digitalRead(CLKPIN)== curr); curr=digitalRead(CLKPIN); #endif // wait for data to settle delayMicroseconds(MIDCLOCK); return(curr); }// end wait4edge // ******* READ CURRENT BIT ******* // returns 0 or 1 for valid bit // returns FRAME for frame bit // returns ERR for other byte getbit(){ int cstate,dat, dat1,dlo; getbits++; cstate=wait4edge(); if(cstate==HI){return(ERR);} // we should always have called on a hi // read data value in 1st half of clock (lo) dat1=digitalRead(DATPIN); cstate=wait4edge(); if(cstate==LO){return(ERR);} // we're now in hi (2nd) half of clock pulse dat=digitalRead(DATPIN); // look for frame // inverted for transistor buffer! dlo=INVERTDATA?LO:HI; if(dat==dlo){ if(dat != dat1){return(FRAME);} return(HI); }else{ if(dat != dat1){return(ERR);}; return(LO); }// end else (LO) }// end getbit() void dumpdata(){ char prbuf[25]; // bunch of debug prints sp("LOs, HIs, getbits, stores: "); sp(los),sps;sp(his);sps;sp(getbits); sps;sp(stores); spl(""); // main data dump sp("dumping data; frames: "); for(int i=0;i