Pages: 1 2 [3] 4   Go Down
Author Topic: Reading data at 10 Khz rate  (Read 16467 times)
0 Members and 1 Guest are viewing this topic.
nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8594
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I think you'll be back soon because you don't have code that will sync with the data yet smiley

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8594
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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
« Last Edit: October 03, 2012, 10:36:39 am by Graynomad » Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 39
Well done is better than well said." --Benjamin Franklin
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.  smiley-sad   smiley-sad
Code:
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;
}
« Last Edit: October 04, 2012, 12:28:33 am by newbee_2 » Logged

Thanx & Regards

Niladri

Offline Offline
Newbie
*
Karma: 0
Posts: 39
Well done is better than well said." --Benjamin Franklin
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Just for curiosity can ISR(edge triggered) be used at that frequency
Logged

Thanx & Regards

Niladri

Brisbane, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.  smiley-sad   smiley-sad
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:
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
Logged

"There is no problem so bad you can't make it worse"
- retired astronaut Chris Hadfield

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8594
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8594
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 39
Well done is better than well said." --Benjamin Franklin
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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     
Logged

Thanx & Regards

Niladri

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 129
Posts: 8594
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Offline Offline
Newbie
*
Karma: 0
Posts: 39
Well done is better than well said." --Benjamin Franklin
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
}
 
Logged

Thanx & Regards

Niladri

Brisbane, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

"There is no problem so bad you can't make it worse"
- retired astronaut Chris Hadfield

Offline Offline
Newbie
*
Karma: 0
Posts: 39
Well done is better than well said." --Benjamin Franklin
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 
Logged

Thanx & Regards

Niladri

Brisbane, Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 1123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Niladri

Can you share the code as you have it presently?

Geoff
Logged

"There is no problem so bad you can't make it worse"
- retired astronaut Chris Hadfield

Offline Offline
Newbie
*
Karma: 0
Posts: 39
Well done is better than well said." --Benjamin Franklin
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry this is the present code
Code:
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);
}
Logged

Thanx & Regards

Niladri

Offline Offline
Newbie
*
Karma: 0
Posts: 39
Well done is better than well said." --Benjamin Franklin
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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);
}
Logged

Thanx & Regards

Niladri

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