Arduino Forum

Topics => Science and Measurement => Topic started by: newbee_2 on Sep 26, 2012, 11:10 am

Title: Reading data at 10 Khz rate
Post by: newbee_2 on Sep 26, 2012, 11:10 am
Hi guys
Can arduino Uno read digital data of 10 KHz frequency?
Thanks in advance
Niladri.
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Sep 26, 2012, 02:26 pm
Hi Niladri

Do you need a serial connection that's 10,000 baud?  Then yes, that's possible with Arduino Uno. 

Geoff
Title: Re: Reading data at 10 Khz rate
Post by: Grumpy_Mike on Sep 26, 2012, 02:46 pm
What form is this data in? Is it serial or parallel?
The arduino has a 16MHz processor so 10KHz is slow, however what are you going to do with it! There is not much room to store very much data, less than a few mS at that rate.
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Sep 26, 2012, 02:48 pm
Thanks for the reply
Actually i need to read a clock of 10 khz and each positive going pulse i need to read data. I have already done using NI LabVIEW and its DAQ card but i want a cheaper replacement so was thinking can i use arduino uno or not?
Is it possible??
Thanks in advance
Niladri. 
Title: Re: Reading data at 10 Khz rate
Post by: Grumpy_Mike on Sep 26, 2012, 02:51 pm
Yes this sounds like an SPI data protocol, look up how to do that.
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Sep 26, 2012, 02:53 pm
Data is parallel and i will send the data to the pc with the help of file write i will store it in the pc(A cheap DAQ at 10 KHz )
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Sep 26, 2012, 02:56 pm
No sir it is not SPI protocol it is more of a Simple Discrete to Serial Converter at 10 KHz clock speed. I am aware of SPI protocol. I have already implemented SPI protocol in arduino.
Title: Re: Reading data at 10 Khz rate
Post by: Grumpy_Mike on Sep 26, 2012, 02:57 pm
Ok we are in blood out of a stone mode. How many bits parallel?
There is a complication in that there is not a free 8 bit port on the arduino so you would have to read them in prices and put them together into bytes to send serially.
Will you need a protocol , or can you just stream it out?
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Sep 26, 2012, 03:13 pm
Thanks everyone for their replies
it is 8 bits and no protocol only serial data
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Sep 27, 2012, 08:15 am
i have written this code but it is not giving me the hex data which i have given as input.
Any suggestion?
Niladri
Code: [Select]
const int pin1 = 2; // the pin where clock will be taken
const int pin2 = 4; // the pin for data input
int count;


void setup()
{
  //  initialize the button pin as a input:
  pinMode(pin1, INPUT);
  //  initialize the button pin as a input:
  pinMode(pin2, INPUT);
  //  Initializing for serial communication
  Serial.begin(9600);
}
void loop()
{
  int clock = digitalRead(pin1); // Reading the clock
   
  if (clock == HIGH) // At each raising edge data should be taken
  {
    int data = digitalRead(pin2); // when a raising edge comes read the data
    count++;
    if(count%4 == 0)
        Serial.print(data, HEX);// Read the data on serial moniter to check logic is right or not
   
  }


Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Sep 27, 2012, 08:49 am
Hi,

You mentioned the data was parallel earlier, but here you're only allowing for one data line, so I'll presume you meant the data was purely serial.

Every time loop() is run, the variable data is recreated losing the previous information.  So while I can see your intention is to read the data line for 4 pulses then output, the only thing you'll ever have to output is the value of the most recent digitalRead (either 0 or 1 being LOW or HIGH) stored in the variable data.  So if you're going to construct the data variable a bit at a time, that variable needs to have a global scope, same as your count variable, and store the bit that you read in the right position within it (via bitset() maybe, or some bitwise math regardless) each iteration of loop() then discard the content on the 4th pass after printing.  Hope that makes sense.

Also while your comment suggests this next test is for a rising edge...
Code: [Select]
if (clock == HIGH) // At each raising edge data should be takenin actual case there's nothing to stop it reading the data line multiple times for any one HIGH pulse of the clock, presuming loop() executes fast enough.  Also, of course there's nothing there to stop it missing out on data if your loop() takes too long, but that's unlikely in this scenario I think.  If you truly need it to be on the rising edge, you might consider implementing this using interrupts; alternatively use an additional check that the clock line is HIGH, but last time through was LOW, and only act when that's the case.

Cheers ! Geoff
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Sep 27, 2012, 12:31 pm
How about you verify the number of bits you need. According to your code it's 4.

There are faults in your code as strykeroz has commented on, but for a start to get 4 bits you need to accumulate the results of 4 digitalRead()s, for example

   
Code: [Select]
loop () {
    static byte val  = 0b00001000;

    if (rising_edge_on_clock_pin) {   // you figure out how to detect this
       val <<= 1;
       val |= digitalRead(pin2);
       if(val | 0x80) {   // flag bit has reached the top of the byte so we've done 4 iterations
           Serial.print(val & 0x7F, HEX);
           val = 0b00001000;
         }
    }
}



______
Rob
Title: Re: Reading data at 10 Khz rate
Post by: Grumpy_Mike on Sep 27, 2012, 03:49 pm
Yes Rob but the big thing he is mixed up about is if the data is serial or parallel. He has said in one post that is was parallel so he needs to read more than one pin and amalgamates the results into one byte before sending it. This might be best doing two reads direct from two ports and oring them together. Choice of the right pins to wire the data to is crucial to making this efficient.
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 01, 2012, 02:48 pm
Sorry for initially mentioning that the data is parallel but now it has converted to serial. I have tried using everybody idea(especially Rob) but yet no fruitful result
Code: [Select]

const int pin2 = 2;
const int pin4 = 4;
int clock;
int clock1;

void setup()
{
  pinMode(pin2, INPUT);
   
  pinMode(pin4, INPUT);
 
  Serial.begin(9600);
}
void loop()
{
  static byte val  = 0b00001000;

    clock = digitalRead(pin2);
    if ((clock == HIGH) && (clock1 == LOW) {   
       val <<= 1;
       val |= digitalRead(pin2);
       if(val | 0x80) {   // flag bit has reached the top of the byte so we've done 4 iterations
           Serial.print(val & 0x7F, HEX);
           val = 0b00001000;
         }
      clock1 = digitalRead(pin2);   
    }
}
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Oct 01, 2012, 03:34 pm
Hi

Two obvious things I think to look at - firstly clock1 isn't initialised, so first pass through it won't have a reliable value.  You can fix that in your declaration:
Code: [Select]
int clock1 = 0;
And the other part is you don't want to set clock1 at the end of the loop to whatever the digital pin value is, but rather what clock was.  Like this:
Code: [Select]
      clock1 = digitalRead(pin2);
// becomes
      clock1 = clock;

Just two thoughts to start you off  :)

Geoff
Title: Re: Reading data at 10 Khz rate
Post by: MichaelMeissner on Oct 01, 2012, 03:41 pm

Hi

Two obvious things I think to look at - firstly clock1 isn't initialised, so first pass through it won't have a reliable value.  You can fix that in your declaration:
Code: [Select]
int clock1 = 0;

Given that clock1 is a global variable, the compiler/runtime system guarantees that it will be 0 when the program starts up.  This is required by the ISO C and C++ standards.  Now, if clock1 were an auto variable, then yes, you would need the initializer.
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Oct 01, 2012, 11:50 pm

Given that clock1 is a global variable, the compiler/runtime system guarantees that it will be 0 when the program starts up.  This is required by the ISO C and C++ standards.  Now, if clock1 were an auto variable, then yes, you would need the initializer.
That's good to know - thanks.  Scratch that one then.
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 03, 2012, 02:28 am
You cannot do a serial.print() in the middle of collecting data at 10kHz. You should collect everything then print the results. I probably should not have put that in there but it depends on how many bits in total are you grabbing. I wrote that for a one-off grab of 4 bits, how many are you grabbing?

Also this

clock1 = digitalRead(pin2);

should be changed to

clock1 = clock;

as has been mentioned and I think it should be moved outside the if block. So loop() looks like this

Code: [Select]
void loop()
{
  static byte val  = 0b00001000;

    clock = digitalRead(pin2);
    if ((clock == HIGH) && (clock1 == LOW) {   
       val <<= 1;
       val |= digitalRead(pin2);
       if(val | 0x80) {   // flag bit has reached the top of the byte so we've done 4 iterations
           Serial.print(val & 0x7F, HEX);
           val = 0b00001000;
         }
     }
     clock1 = clock;   
}


Still only good for one sample though because of the serial.print()

What is this data and what is it coming from? At that speed you won't be able to keep up unless there's a break at some point to allow you time to do something with the data.


______
Rob
Title: Re: Reading data at 10 Khz rate
Post by: Grumpy_Mike on Oct 03, 2012, 04:37 am
This is a major problem
Code: [Select]
  Serial.begin(9600);
At this speed you can only output 960 chars per second. You are printing hex, that is 2 chars per byte so that is twenty times too slow.

Plus other stuff mentioned already.
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 03, 2012, 06:07 am
Many thanks to everybody for their response
the Data is coming from a decoding device and it is continuously running for 1-2 hours
I just need to send those data to PC as like serial data because pc cannot read discrete input.   
Thanks in advance
Niladri
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 03, 2012, 09:22 am
You have to up the serial port bit rate as Mike said, use 115200 and get the serial over with fast.

But I suspect that you will have another problem. What is the format of this data? Is each 4 bits a unique value or just part of a continuous bit stream. If it's a unique value you have to sync with the nibbles and with SPI that's all but impossible without another input or a longish time delay between nibbles.

Before working any more with code we need to know the exact nature of the incoming bits and the timing between the groups of four.

Quote
Data is coming from a decoding device

Data sheet?

______
Rob
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 03, 2012, 09:34 am
Decoding device is under process(We are building our own homemade BCH decoder)
You can say it is filter tuned for 5.5 khz and 3.125 khz and it generates pulses and clock recovery system recover 10 khz clock now output from the 3.125 khz is passed through not gate to get stream of 128 bits(0 and 1) now each positive edge we need to read the value and each nibble we need convert to serial data and send it to pc. AS i said before it is like data acquisition system which can sample at 10 khz rate discrete input
If you have any other inquiry please let me know
Thanks in advance
Niladri   
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 03, 2012, 10:16 am
Ok,

1. If there's 128 bits why do you need to grab them in nibbles.
2. Is there any space/extra time between the nibbles?
3. Is there any space/extra time between the 128-bit packets?
4. What is the format of each nibble?
5. Is there any way to detect the start/end of a 128-bit packet?

All this is leading to how do you sync with the data stream? If there is no spaces between nibbles and/or packets it is well nigh impossible to sync if you get out of whack.

EDIT: #5 added.
______
Rob
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 03, 2012, 11:50 am
No first 24 bit will be CAAC1F(in HEX) if it is then receive next 96 bits otherwise slide to next bit until it matches the string but the string matching is done on a PC where LabVIEW software is running so my job is to silde it until i get send all 96 bits command from labview

And this code is somewhat working can you take a look at it.
Code: [Select]

const int pin2 = 2;
const int pin4 = 4;
int clock;
int clock1;
int val1;
int val2;
int val3;
int val4;
int val5;
int val6;
int val7;
int val8;
byte value =0000000;

void setup()
{
 pinMode(pin2, INPUT);
 
 pinMode(pin4, INPUT);
 
 Serial.begin(2400);
}
void loop()
{
 static byte val  = 0b00000001;

   clock = digitalRead(pin2);
   if ((clock == HIGH) & (clock1 == LOW)) {  
      val <<= 1;
      val1 = digitalRead(pin4);
      val2 = digitalRead(pin4);
      val3 = digitalRead(pin4);
      val4 = digitalRead(pin4);
      val5 = digitalRead(pin4);
      val6 = digitalRead(pin4);
      val7 = digitalRead(pin4);
      val8 = digitalRead(pin4);
            if(val | 0x80) {   // flag bit has reached the top of the byte so we've done 8 iterations
         
          value=(value | (val1<<7));
          value=(value | (val2<<6));
          value=(value | (val3<<5));
          value=(value | (val4<<4));
          value=(value | (val5<<3));
          value=(value | (val6<<2));
          value=(value | (val7<<1));
          value=(value | (val8<<0));
         
         
         
          Serial.print(value & 0xFF, HEX);
          val = 0b00000001;
        }
       
   }
   clock1= clock;
}


And for your questions
1. I need to send them as hex format for labview understanding
2. No
3. No
4. HEX
5. Keep on sending that Data till i receive a command from pc send next 96 bits of data that data also need to in HEX format fro labview understanding.
Thanks in Advance
Niladri  
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 03, 2012, 12:58 pm
Sorry for that last code
Code: [Select]

const int pin2 = 2;
const int pin4 = 4;
int clock;
int clock1;

void setup()
{
  pinMode(pin2, INPUT);
   
  pinMode(pin4, INPUT);
 
  Serial.begin(2400);
}
void loop()
{
  static byte val  = 0b00000001;

    clock = digitalRead(pin2);
    if ((clock == HIGH) && (clock1 == LOW)) {   
       val <<= 1;

         val |= digitalRead(pin4);
             if(val | 0x80) {   // flag bit has reached the top of the byte so we've done 8 iterations
           

           
                     
           Serial.print(val & 0x7F, HEX);
           Serial.println();
           val = 0b00000001;
         }
   
    }
    clock1= clock;
}
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Oct 03, 2012, 01:28 pm

No first 24 bit will be CAAC1F(in HEX) if it is then receive next 96 bits otherwise slide to next bit until it matches the string but the string matching is done on a PC where LabVIEW software is running so my job is to silde it until i get send all 96 bits command from labview

And this code is somewhat working can you take a look at it.
...
And for your questions
1. I need to send them as hex format for labview understanding
2. No
3. No
4. HEX
5. Keep on sending that Data till i receive a command from pc send next 96 bits of data that data also need to in HEX format fro labview understanding.
Thanks in Advance
Niladri 
If I'm understanding you correctly, until you get a CAAC1F pattern match of the fixed pre-amble for the next frame/packet you won't know the bit boundary to start your 4-bit values on.  Since that's the information you can use to synchronise your serial comms you will need to do the pattern matching on your Arduino rather than the PC or you'll not be guaranteed to be sending data that's aligned to the correct 4 bit boundaries.  You can encode any arbitrary 4 bit pattern as hex and send it to the PC, but unless it's conforming to the correct 4-bit boundary your data will be meaningless.

If you know the CAAC1F pattern will be the preamble to every 128 bit data frame received, you can also use this as a mechanism to partially validate the most recent data received (ie once you've received 96 bits the next received data must be CAAC1F, or that previous data buffer is invalid).

Geoff
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 03, 2012, 01:35 pm
Quote
Sorry for that last code

Thank goodness, I was getting worried.

So as I understand it you keep feeding bytes (with the sampled nibbles in the lower 4 bits) to the PC, the PC reads 32 ASCII HEX chars, if it doesn't see 'C','A','A','C','1','F' after 32 bytes it tells you to move a bit and the whole process starts again. At some point the start sequence is found and you are off and racing.

I think you should do this on behalf of the PC because I doubt there is enough time to get the command from the PC, you only have 100nS and a PC can't do anything reliably in that time.

_____
Rob
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 03, 2012, 01:41 pm
Through another arduino i am feeding 0x0F but in other arduino(receiver) i am reading all kind of junk values but not 0x0F what could be the mistake on my part
Code: [Select]

const int pin2 = 2;
const int pin4 = 4;
int clock;
int clock1;



void setup()
{
  pinMode(pin2, INPUT);
   
  pinMode(pin4, INPUT);
 
  Serial.begin(2400);
}
void loop()
{
  static byte val  = 0b00000001;
  static byte value = 0b00000000;

    clock = digitalRead(pin2);
    if ((clock == HIGH) && (clock1 == LOW)) {   
       val <<= 1;

         value |= digitalRead(pin4);
         value <<= 1;
             if(val | 0x80) {   // flag bit has reached the top of the byte so we've done 8 iterations
           

           
                     
           Serial.print(value, HEX);
           Serial.println();
           val = 0b00000001;
          // value = 0b00000000;
         
         }
   
   
    }
    clock1= clock;
}

Thanks in advance
Niladri
Title: Re: Reading data at 10 Khz rate
Post by: MichaelMeissner on Oct 03, 2012, 02:07 pm

Through another arduino i am feeding 0x0F but in other arduino(receiver) i am reading all kind of junk values but not 0x0F what could be the mistake on my part
Code: [Select]

if(val | 0x80) {   // flag bit has reached the top of the byte so we've done 8 iterations


This doesn't do what you think it does, since the '|' operator is an OR, and the if statement will always be true.  What you want is '&' which is an AND.  I.e.:

Code: [Select]

if (val & 0x80) {


Now personally, I tend to prefer writing the above expression as:

Code: [Select]

if ((val & 0x80) != 0) {


You have mixed up the logic in that you should do the shift of value before doing the read and not after.

I would make 'val' a simple counter (and call it a more meaningful name).  Something like:

Code: [Select]

void loop()
{
     static byte num_bits  = 0;
     static byte value = 0;

     clock = digitalRead(pin2);
     if ((clock == HIGH) && (clock1 == LOW))
        {   
            value = (value << 1) | digitalRead (pin4);
            if (++num_bits >= 8)                          // have we done 8 iterations?  If so print it out
                {
                     Serial.print(value, HEX);
                     Serial.println();
                     num_bits = 0;
                    value = 0;
                }
        }

    clock1= clock;
}
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 03, 2012, 02:50 pm
Thanks a lot sir it is working cann't express the joy of seeing it works in words
Thanks thanks thanks and also my respect and gratitude to all Rob, Geoff , Mike without your help and suggestion it would have not been possible

Thanks to everybody for response will come back to you when stuck with another problem(i have very little knowledge so it is highly unlikely that i can say something anybody problem)

Thanks a lot
Niladri
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 03, 2012, 03:25 pm
I think you'll be back soon because you don't have code that will sync with the data yet :)

______
Rob
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 03, 2012, 04:46 pm
This seemed like an interesting problem so I spent a little time working on some code because I think you are still a long way from having a real solution.

It's a problem crying out for a state machine so here is my first pass

Code: [Select]
const int CLOCK_PIN     =     2;
const int DATA_PIN      =     4;
const int PACKET_BITS   =     128;
const int PREAMBLE_LEN  =    6;
const int DATA_LEN      =    ((PACKET_BITS / 4) - PREAMBLE_LEN);

enum {
    PRE_0,    PRE_1,    PRE_2,    PRE_3,    PRE_4,    PRE_5,    DATA
} states;   

byte     preamble [] = {0x0C,0x0A,0x0A,0x0C,0x01,0x0F};
char     hexAsciiVals[] = "0123456789ABCDEF";
byte     state = PRE_0;
byte     nibble;
int        nibble_count = 0;

void setup() {
  pinMode(CLOCK_PIN, INPUT);
  pinMode(DATA_PIN, INPUT);
  Serial.begin(115200);
}

void loop() {

    nibble = getNibble();
    nibble_count++;
   
    switch (state) {   
        case PRE_0:
            if (nibble_count > PREAMBLE_LEN + DATA_LEN) {
                // we've read 32 bytes and still not found a match
                // for the preamble so skip a clock pulse
                while (digitalRead(CLOCK_PIN) == HIGH);
                while (digitalRead(CLOCK_PIN) == LOW);
                nibble_count = 0;
            } else {
                state = (nibble == preamble[0]) ? PRE_0 : PRE_1;
            }
            break;
       
        case PRE_1:
            state = (nibble == preamble[1]) ? PRE_0 : PRE_2;   
            break;
           
        case PRE_2:
            state = (nibble == preamble[2]) ? PRE_0 : PRE_3;
            break;

        case PRE_3:
            state = (nibble == preamble[3]) ? PRE_0 : PRE_4;
            break;

        case PRE_4:
            state = (nibble == preamble[4]) ? PRE_0 : PRE_5;
            break;
       
        case PRE_5:
            state = (nibble == preamble[5]) ? PRE_0 : DATA;
            break;
           
        case DATA:
            Serial.write (hexAsciiVals[nibble]);
            if (nibble_count == DATA_LEN) {
                // all done, start again
                state = PRE_0;
                nibble_count = 0;
            }
            break;
    }
}

byte getNibble() {

    byte val = 0;
   
    for (byte bit_count = 0; bit_count < 4; bit_count++) {
        while (digitalRead(CLOCK_PIN) == HIGH);
        while (digitalRead(CLOCK_PIN) == LOW);
        val <<= 1;
        val |= digitalRead(DATA_PIN);
    }
    return (val &= 0x0F);
}


It compiles but I may have stuffed up some logic, hopefully not.

As the states are contiguous you could probably replace some of the switch() cases with a simple state++ but I think this allows for changes to be more easily implemented.

______
Rob
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 04, 2012, 06:56 am
Yes you are absolutely right though its reads corrects value some times but once its looses its sync it does take lot of value to again com its actual position. So what could i do to make to once it looses its sync on next or in 2-3 iteration its sync again.  :(   :(
Code: [Select]

const int pin2 = 2;
const int pin4 = 4;
int clock = 0;
int clock1 = 0;



void setup()
{
  pinMode(pin2, INPUT);
   
  pinMode(pin4, INPUT);
 
  Serial.begin(2400);
}
void loop()
{
     static byte num_bits  = 0;
     static byte value = 0;

     clock = digitalRead(pin2);
     if ((clock == HIGH) && (clock1 == LOW))
        {   

           
            value = (value << 1) | digitalRead (pin4);
            if (++num_bits >= 8)                          // have we done 8 iterations?  If so print it out
                {
                     Serial.print(value, HEX);
                     Serial.println();
                     num_bits = 0;
                    value = 0;
                }
        }

    clock1= clock;
}
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 04, 2012, 08:01 am
Just for curiosity can ISR(edge triggered) be used at that frequency
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Oct 04, 2012, 09:03 am

Yes you are absolutely right though its reads corrects value some times but once its looses its sync it does take lot of value to again com its actual position. So what could i do to make to once it looses its sync on next or in 2-3 iteration its sync again.  :(   :(
Reading through Rob's code,  if it loses its way, it will/should pick up the next preamble characters so long as the 4-bit boundary is maintained.  So if you've got out of sync by 1, 2 or 3 bits one way to potentially make it pick up the trail sooner is to construct a state machine looking for the pattern of bits of the preamble rather than the sequence of nibbles (which wouldn't be found if you are no longer sampling nibbles at the correct bit boundary).  Also, presuming there's a bit on every high clock pulse I'm wondering if the marked line below, will mean the first ever bit in the stream is always lost which would throw it out of sync from the start?
Code: [Select]
byte getNibble() {

    byte val = 0;
   
    for (byte bit_count = 0; bit_count < 4; bit_count++) {
        while (digitalRead(CLOCK_PIN) == HIGH);  // <<< THIS LINE
        while (digitalRead(CLOCK_PIN) == LOW);
        val <<= 1;
        val |= digitalRead(DATA_PIN);
    }
    return (val &= 0x0F);
}
You do say it works, so I presume I'm wrong on that point.

Geoff
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 04, 2012, 09:55 am
It might get a bit tight Geoff, after getting a nibble you have ~100uS to get back to the getNibble() function. If you don't make it you are out of sync again. I'll have a think about the timing but it may be better to put that code inline, at least that will save a function call.

Quote
You do say it works, so I presume I'm wrong on that point.

I'm not sure newbee_2 is using my code.

One thing I/we didn't think of is that presumably the PC still needs to see the preamble as it doesn't know all this is happening. So after we get in sync we need to send those 6 bytes.

_____
Rob
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 04, 2012, 03:57 pm
Quote
can ISR(edge triggered) be used at that frequency

Yes, and that may be a good way to go. But if we're worried about having enough time interrupts will make it worse.

______
Rob
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 05, 2012, 07:55 am
Ok this code is most efficient so far once it goes out of Sync in 2-3 iteration it comes back but they are saying make it like sliding window and you keep on sliding 1 bit at a time until you found the match("CAAC1F") and when found send it reaming bits(128-24=104) and again start the process. Can it be done?
Thanks and Regards
Niladri   
Title: Re: Reading data at 10 Khz rate
Post by: graynomad on Oct 05, 2012, 09:19 am
Quote
this code is most efficient so far

Which code are we talking about now?

Quote
2-3 iteration

What is an "iteration" in this context?

Quote
Can it be done?

I think that's what my example did but I haven't revisited it because I don't know if you have tried it or not.

______
Rob
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Oct 05, 2012, 09:35 am
The code on post 32.
Some time that code also looses its Sync but once it looses it comes back after 2-3 wrong value
No in that code you have checked only 32 byte and after you skip a pules but data stream is continuous so pulse skip might not possible

Code: [Select]

const int CLOCK_PIN     =     2;
const int DATA_PIN      =     4;
const int PACKET_BITS   =     128;
const int PREAMBLE_LEN  =    6;
const int DATA_LEN      =    ((PACKET_BITS / 4) - PREAMBLE_LEN);

enum {
    PRE_0,    PRE_1,    PRE_2,    PRE_3,    PRE_4,    PRE_5,    DATA
} states;   

byte     preamble [] = {0x0C,0x0A,0x0A,0x0C,0x01,0x0F};
char     hexAsciiVals[] = "0123456789ABCDEF";
byte     state = PRE_0;
byte     nibble;
int        nibble_count = 0;

void setup() {
  pinMode(CLOCK_PIN, INPUT);
  pinMode(DATA_PIN, INPUT);
  Serial.begin(9600);
}

void loop() {

    nibble = getNibble();
    nibble_count++;
   
    switch (state) {   
        case PRE_0:
            if (nibble_count > 32) { // I made this change for my own understanding
                // we've read 32 bytes and still not found a match
                // for the preamble so skip a clock pulse
                while (digitalRead(CLOCK_PIN) == HIGH);
                while (digitalRead(CLOCK_PIN) == LOW);
                nibble_count = 0;
            } else {
                state = (nibble == preamble[0]) ? PRE_0 : PRE_1;
            }
            break;
       
        case PRE_1:
            state = (nibble == preamble[1]) ? PRE_0 : PRE_2;   
            break;
           
        case PRE_2:
            state = (nibble == preamble[2]) ? PRE_0 : PRE_3;
            break;

        case PRE_3:
            state = (nibble == preamble[3]) ? PRE_0 : PRE_4;
            break;

        case PRE_4:
            state = (nibble == preamble[4]) ? PRE_0 : PRE_5;
            break;
       
        case PRE_5:
            state = (nibble == preamble[5]) ? PRE_0 : DATA;
            break;
           
        case DATA:
            Serial.write (hexAsciiVals[nibble]);
            if (nibble_count == DATA_LEN) {
                // all done, start again
                state = PRE_0;
                nibble_count = 0;
            }
            break;
    }
}

byte getNibble() {

    byte val = 0;
   
    for (byte bit_count = 0; bit_count < 4; bit_count++) {
        while (digitalRead(CLOCK_PIN) == HIGH);
       
          while (digitalRead(CLOCK_PIN) == LOW);
       
          val <<= 1;
          val |= digitalRead(DATA_PIN);
       
         
    }
    return (val &= 0x0F);
}
 
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Oct 05, 2012, 09:44 am
So if it goes out of sync it recovers with the loss of no more than 3 frames of data.  Is that acceptable to you or do you need to refine that further?
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Nov 13, 2012, 08:07 am
Hi guys I am back with another problem.
If i want to read the data exactly on each rising edge using interrupt how to approach that way???
All other things mentioned earlier still remains same ( reading "CAAC1F" and match found read the next remaining 32 bytes of data).
I have never written an ISR and pretty clueless how to set the proper register(currently i am going through the datasheet but without any background knowledge i am struggling a lot)
Any help???
Thanks in advance
Niladri 
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Nov 13, 2012, 08:42 am
Hi Niladri

Can you share the code as you have it presently?

Geoff
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Nov 13, 2012, 09:17 am
Sorry this is the present code
Code: [Select]

const int CLOCK_PIN     =    2;
const int DATA_PIN      =    4;
const int PACKET_BITS   =    128;
const int PREAMBLE_LEN  =    6;
const int DATA_LEN      =    26;

enum {
   PRE_0,    PRE_1,    PRE_2,    PRE_3,    PRE_4,    PRE_5,    DATA
} states;    

byte     preamble [] = {0x0C,0x0A,0x0A,0x0C,0x01,0x0F};
char     hexAsciiVals[] = "0123456789ABCDEF";
byte     state = PRE_0;
byte     nibble;
int        nibble_count = 0;

void setup() {
 pinMode(CLOCK_PIN, INPUT);
 pinMode(DATA_PIN, INPUT);
 Serial.begin(115200);
}

void loop() {

   nibble = getNibble();
   nibble_count++;
   
//    Serial.print(digitalRead(CLOCK_PIN));
   
   switch (state) {    
       case PRE_0:
           if (nibble_count > 32) {
               // we've read 32 bytes and still not found a match
               // for the preamble so skip a clock pulse
               while (digitalRead(CLOCK_PIN) == LOW);
               while (digitalRead(CLOCK_PIN) == HIGH);
               nibble_count = 0;
           }
           else
           {
               if(nibble == preamble[0])
                     state = PRE_1;
               else
                     state = PRE_0;
           }
           break;
           
       case PRE_1:
           if(nibble == preamble[1])
                state = PRE_2;
           else
                state = PRE_0;    
           break;
           
       case PRE_2:
           if(nibble == preamble[2])
               state = PRE_3;
           else
               state = PRE_0;
           break;
           
       case PRE_3:
           if(nibble == preamble[3])
              state = PRE_4;
           else
              state = PRE_0;
           break;
           
       case PRE_4:
           if(nibble == preamble[4])
             state = PRE_5;
           else
             state = PRE_0;
           break;
           
       case PRE_5:
           if(nibble == preamble[5])
            state = DATA;
           else
            state = PRE_0;
           break;
           
       case DATA:
           Serial.print (hexAsciiVals[nibble]);
           if (nibble_count == DATA_LEN) {
               // all done, start again
               state = PRE_0;
               nibble_count = 0;
               Serial.println();
           }
           break;
   }
}

byte getNibble() {

   byte val = 0;
   
   for (byte bit_count = 0; bit_count < 4; bit_count++) {
       while (digitalRead(CLOCK_PIN) == HIGH);
       
         while (digitalRead(CLOCK_PIN) == LOW);
         val <<= 1;
         val |= digitalRead(DATA_PIN);
       }
   return (val &= 0x0F);
}
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Nov 23, 2012, 11:36 am
Finally it's working thanks everyone for their help and support without your help it would not been possible and i am posting the working code if in case anyone wants to refer it for their future use....
Thanks...
Code: [Select]

const int CLOCK_PIN     =     2;
const int DATA_PIN      =     4;
const int PACKET_BITS   =     256;
const int PREAMBLE_LEN  =     6;
const int DATA_LEN      =     ((PACKET_BITS / 4) - PREAMBLE_LEN);

enum {
    PRE_0,    PRE_1,    PRE_2,    PRE_3,    PRE_4,    PRE_5,    DATA
} states;   

byte     preamble [] = {0x0C,0x0A,0x0A,0x0C,0x01,0x0F};
char     hexAsciiVals[] = "0123456789ABCDEF";
byte     state = PRE_0;
byte     nibble;
int      nibble_count = 0;
byte     firstval;

void setup() {
  pinMode(CLOCK_PIN, INPUT);
  pinMode(DATA_PIN, INPUT);
  Serial.begin(9600);
}

void loop() {

    nibble = getNibble();
    //nibble_count++;
   
   
    switch (state) {   
        case PRE_0:
//            if (nibble_count > PREAMBLE_LEN + DATA_LEN) {
//                // we've read 32 bytes and still not found a match
//                // for the preamble so skip a clock pulse
//                while (digitalRead(CLOCK_PIN) == LOW);
//                while (digitalRead(CLOCK_PIN) == HIGH);
//                nibble_count = 0;
//            } else
//            {
//                firstval = 12;
//                Serial.write(hexAsciiVals[firstval]);
               
                state = (nibble == preamble[0]) ? PRE_1 : PRE_0;
              //  Serial.write(hexAsciiVals[nibble]);
//            }
            break;
       
        case PRE_1:
           
           // Serial.write (hexAsciiVals[firstval]);
           // Serial.print(hexAsciiVals[12]);
            Serial.print(hexAsciiVals[nibble]);
            state = (nibble == preamble[1]) ? PRE_2 : PRE_0;   
            //Serial.write (hexAsciiVals[nibble]);
            break;
           
        case PRE_2:
            Serial.print(hexAsciiVals[nibble]);
            state = (nibble == preamble[2]) ? PRE_3 : PRE_0;
            //Serial.write (hexAsciiVals[nibble]);
            break;

        case PRE_3:
            Serial.print(hexAsciiVals[nibble]);
            state = (nibble == preamble[3]) ? PRE_4 : PRE_0;
            //Serial.write (hexAsciiVals[nibble]);
            break;

        case PRE_4:
            Serial.print(hexAsciiVals[nibble]);
            state = (nibble == preamble[4]) ? PRE_5 : PRE_0;
            //Serial.write (hexAsciiVals[nibble]);
            break;
       
        case PRE_5:
            Serial.print(hexAsciiVals[nibble]);
            state = (nibble == preamble[5]) ? DATA : PRE_0;
            //Serial.write (hexAsciiVals[nibble]);
            //   nibble_count = 0;
            break;
           
        case DATA:
           
            Serial.print(hexAsciiVals[nibble]);
            if (nibble_count == DATA_LEN) {
                // all done, start again
                state = PRE_0;
                nibble_count = 0;
                Serial.println(' ');
                Serial.print(hexAsciiVals[12]);
               
            }
           
            nibble_count++;
            //Serial.println();
            break;
    }
   
  //  delay(10);
}

byte getNibble() {

    byte val = 0;
   
    for (byte bit_count = 0; bit_count < 4; bit_count++) {
        while (digitalRead(CLOCK_PIN) == HIGH);
        while (digitalRead(CLOCK_PIN) == LOW);
        val <<= 1;
        val |= digitalRead(DATA_PIN);
    }
    return (val &= 0x0F);
}
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Jan 10, 2013, 11:54 am
Just for curiosity i tried to read byte by byte rather than nibble by nibble but it does not read the data at all. Can anybody indicate where i am doing wrong.

Code: [Select]

const int CLOCK_PIN     =     2;
const int DATA_PIN      =     4;
const int PACKET_BITS   =     1024;
const int PREAMBLE_LEN  =     3;
const int DATA_LEN      =     ((PACKET_BITS / 8) - PREAMBLE_LEN);

enum {
    PRE_0,    PRE_1,    PRE_2,    PRE_3,    PRE_4,    PRE_5,    DATA
} states;   

byte     preamble [] = {0xCA,0xAC,0x1F};
char     hexAsciiVals[] = "0123456789ABCDEF0123456789ABCDEF";
byte     state = PRE_0;
byte     nibble;
int      nibble_count = 0;
byte     firstval;
//const char  header = "CAAC1F";

void setup() {
  pinMode(CLOCK_PIN, INPUT);
  pinMode(DATA_PIN, INPUT);
  Serial.begin(57600);
}

void loop() {

    nibble = getNibble();
    //nibble_count++;
   
   
    switch (state) {   
        case PRE_0:
//            if (nibble_count > PREAMBLE_LEN + DATA_LEN) {
//                // we've read 32 bytes and still not found a match
//                // for the preamble so skip a clock pulse
//                while (digitalRead(CLOCK_PIN) == LOW);
//                while (digitalRead(CLOCK_PIN) == HIGH);
//                nibble_count = 0;
//            } else
//            {
//                firstval = 12;
//                Serial.write(hexAsciiVals[firstval]);
               
                state = (nibble == preamble[0]) ? PRE_1 : PRE_0;
              //  Serial.write(hexAsciiVals[nibble]);
//            }
            break;
       
        case PRE_1:
           
           // Serial.write (hexAsciiVals[firstval]);
           // Serial.print(hexAsciiVals[12]);
           // Serial.print(hexAsciiVals[nibble]);
            state = (nibble == preamble[1]) ? PRE_2 : PRE_0;   
            //Serial.write (hexAsciiVals[nibble]);
            break;
           
        case PRE_2:
          //  Serial.print(hexAsciiVals[nibble]);
            state = (nibble == preamble[2]) ? DATA : PRE_0;
            //Serial.write (hexAsciiVals[nibble]);
            break;

//        case PRE_3:
//          //  Serial.print(hexAsciiVals[nibble]);
//            state = (nibble == preamble[3]) ? PRE_4 : PRE_0;
//        //    Serial.write (hexAsciiVals[nibble]);
//            break;
//
//        case PRE_4:
//           // Serial.print(hexAsciiVals[nibble]);
//            state = (nibble == preamble[4]) ? PRE_5 : PRE_0;
//           // Serial.write (hexAsciiVals[nibble]);
//            break;
//       
//        case PRE_5:
//           // Serial.print(hexAsciiVals[nibble]);
//    //        Serial.print(202, HEX);
//  //          Serial.print(172, HEX);
//        //    Serial.println();
//            state = (nibble == preamble[5]) ? DATA : PRE_0;
//            Serial.print("$");
//            //   nibble_count = 0;
//            break;
           
        case DATA:
           //   Serial.print("CAAC1F");
            Serial.print(nibble, HEX);
            if (nibble_count == DATA_LEN) {
                // all done, start again
                state = PRE_0;
                nibble_count = 0;
             //   Serial.print("\n");
           //     Serial.print(hexAsciiVals[12]);
               
            }
           
            nibble_count++;
            //Serial.println();
            break;
    }
   
  //  delay(10);
}

byte getNibble() {

    byte val = 0;
   
    for (byte bit_count = 0; bit_count < 8; bit_count++) {
        while (digitalRead(CLOCK_PIN) == HIGH);
        while (digitalRead(CLOCK_PIN) == LOW);
        val <<= 1;
        val |= digitalRead(DATA_PIN);
    }
    return (val &= 0xFF);
}
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Jan 10, 2013, 02:10 pm
Hi,

This thread takes me back :) 

Rob's state machine was based on testing the 4 bit nibbles, so you'd have to rewrite that too, not just the getNibble() function.  I'd be concerned though that while the previous logic could be out of sync with the stream by up to 3 bits, this could get lost by up to 7.  This would lead to potentially more than double the data loss on those occasions while the sketch found the correct preamble again.

Why would you want to do it byte by byte?  Didn't you have this working as at your previous post?

Geoff
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Jan 11, 2013, 05:11 am
No it is working fine and there no necessity for me make it 8 bit but for just better understanding that if the state machine works for 4 bit then if we do slight modification on the state machine it should work for 8 bit. So i modified the state machine as well as getNibble() function but it does not read any data so i came to forum for possible solution(I am work alone so i have no other alternative). :)
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Jan 11, 2013, 05:53 am
Okay,

So for the sake of the exercise then :)

Can I ask why have you commented out the block at the start of case PRE_0: ?  Without it surely if you start out of sync there's no way it can recover, so it could read the entire stream without ever discovering a valid preamble therefore will never find you any data. 

Geoff
Title: Re: Reading data at 10 Khz rate
Post by: newbee_2 on Jan 11, 2013, 06:44 am
That's true but i need to shift bit by bit until i find a match so skipping a clock might not be best method as the data might be the particular preamble first bit(the preamble can be anywhere i don't where it starts so shift bit by bit 1st until match found).
Title: Re: Reading data at 10 Khz rate
Post by: strykeroz on Jan 11, 2013, 07:19 am
Skipping a clock is just ignoring the next one bit so the next frame is read from 1 bit to the right in alignment down the stream.  It's only done when there's been a full frame length read without finding a preamble (which means it's out of sync and always would be). 

Where is your code for returning to alignment if you're not doing that?