Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: Weird digitaiRead() behavior in the SPI part of my project..

  1. #1
    Junior Member
    Join Date
    Feb 2014
    Location
    Vancouver WA
    Posts
    10

    Weird digitaiRead() behavior in the SPI part of my project..

    Hi Folks;

    I'm sure I'm doing something simple wrong but am getting incorrect data in my attempt to
    read data back from an SPI slave.

    The data is showing correctly on the logic analyzer but received wrong in the Arduino
    program.

    In the attached code I did not believe that my serial output was correct so I output the two read
    bytes immediately to a bogus SPI to see what I received..

    My snippet.. (Whole Program below..)

    digitalWrite(adcCS, LOW);
    transfer(cmd1);
    r1 = transfer(cmd2);
    r2 = transfer(0);
    digitalWrite(adcCS, HIGH);

    digitalWrite(otherCS, LOW);
    transfer(r1);
    transfer(r2);
    digitalWrite(otherCS, HIGH);

    If you look at the logic analyzer trace the r1 and r2 bytes I tried to read in the actual ADC
    read are incorrect but they do agree with the serial data.

    the transfer() is giving me the same bazzar results it I use the SPI library or bit-bang the SPI.

    Click image for larger version. 

Name:	Capture.JPG 
Views:	209 
Size:	241.3 KB 
ID:	1709


    Also when I try just to read a pin hooked to high or ground it's not reading the value correctly..

    Questions:
    1) Are Teensy 3.1 pins identified differently like they are in the 2.0 when used with arduino so I;'m using the wrong pin?
    2) Is there something silly I'm doing wrong.

    Teensy 3.1
    Arduino 1.0.5-r2
    TeensyDuino 1.18
    SPI talking to an Isolation IC ADuM7441
    and 4-channel ADC on the far side of that MCP3302

    Click image for larger version. 

Name:	imageSmall.jpeg 
Views:	257 
Size:	140.5 KB 
ID:	1710

    Full Source:
    PHP Code:
    // kill_a_watt.c
    // code to read ADC on the watt meter..

    #define BANG_SPI
    #ifdef BANG_SPI
    const int BSCK    13;
    const 
    int BMOSI   11;
    const 
    int BMISO   12;
    #define transfer(x) spiBangTransfer((x))
    #else
    #include <SPI.h>
    #define transfer(x) SPI.transfer((x))
    #endif


    const int greenLedPin =  5;
    const 
    int redLedPin =  7;
    const 
    int adcCS  10;
    const 
    int dio23 23;
    const 
    int otherCS 9;

    // the setup() method runs once, when the sketch starts
    char bbuf[128];

    void setup() {
      
    // initialize the digital pin as an output.
      
    pinMode(greenLedPinOUTPUT);
      
    pinMode(redLedPinOUTPUT);
      
    pinMode(adcCSOUTPUT);
      
    pinMode(otherCSOUTPUT);
      
    pinMode(0INPUT);
      
    digitalWrite(otherCSHIGH);
      
    digitalWrite(adcCSHIGH);
      
    #ifdef BANG_SPI
      
    pinMode(BSCKOUTPUT);
      
    pinMode(BMOSIOUTPUT);
      
    pinMode(BMISOINPUT_PULLUP);
      
    digitalWrite(BSCKLOW);
      
    digitalWrite(BMOSILOW);
      
    #endif
      
    digitalWrite(redLedPinHIGH);
      
    digitalWrite(greenLedPinHIGH);
      
    Serial.begin(38400);
      
    #ifndef BANG_SPI
      // start the SPI library:
      
    SPI.begin();
    #endif
     
    }

    void report(int count)
    {
      
    double va;
      
    char buf[128];

      
    cos((double)count 100)*4.5;
      
    cos((double)count 120)*3.5;
      
      
    sprintf(buf"v:%15.6lf  a:%15.6lf c:%d\n"vacount);
      
    Serial.println(buf);
    }

    #ifdef BANG_SPI
    char spiBangTransfer(char SPIDataOut)
    {
        
    unsigned char SPICount;                               // Counter used to clock out the data
        
    unsigned char SPIDataIn 0;

        
    digitalWrite(BSCK,LOW);
        
        for (
    SPICount 0SPICount 8SPICount++)
        {
            
    digitalWrite(BMOSI, (SPIDataOut 0x80));      // set Output bit
            
    digitalWrite(BSCKHIGH);                        // Clock Rising Edge
            
    SPIDataIn += (digitalRead(BMISO)&1);               // Read the data bit
            
    digitalWrite(BSCKLOW);
            
    SPIDataOut <<= 1;
            
    SPIDataIn <<= 1;
        }                                        
        
    digitalWrite(BMOSI,LOW);              
        
        return (
    SPIDataIn);                      
    }
    #endif


    int16_t readAdcChannel(int channel)
    {
      
    char cmd2;
      
    char cmd1 0x18 channel;
      
    char r1r2;
      
    uint16_t res;
      
      
    cmd2 cmd1 << 7;
      
    cmd1 cmd1 >> 1;
      
      
    digitalWrite(adcCSLOW);
      
    transfer(cmd1); 
      
    r1 transfer(cmd2);
      
    r2 transfer(0);
      
    digitalWrite(adcCSHIGH);
      
      
    digitalWrite(otherCSLOW);
      
    transfer(r1);
      
    transfer(r2);
      
    digitalWrite(otherCSHIGH);
      
      
      
    sprintf(bbuf"r1: 0x%02x,  r2: 0x02x, D0:%d D23:%d"r1r2, (digitalRead(0) & 0x01), (digitalRead(dio23) & 0x01));
      
    Serial.println(bbuf);
      
      
    res r1;
      
    res = (res << 8) + r2;
      
    res res 0x0fff;
      
      return 
    res;
    }


    void loop() 
    {
      static 
    int count;
      static 
    int ledState 0;
      
    char dat;
      
      
    digitalWrite(greenLedPinledState);   // set the LED
      
    ledState = ! ledState;

      
    sprintf(bbuf"c0:%d c1:%d c2:0d"readAdcChannel(0), readAdcChannel(1), readAdcChannel(2));
      
    Serial.println(bbuf);
    //  report(count);
      
    count ++;
      
    delay(1000);  


    Gives the output...

    PHP Code:
    r10x8c,  r20x02xD0:48 D23:1
    r1
    0x8c,  r20x02xD0:48 D23:1
    r1
    0x8c,  r20x02xD0:50 D23:1
    c0
    :3120 c1:3120 c2:0d
    r1
    0x8c,  r20x02xD0:50 D23:1
    r1
    0x8c,  r20x02xD0:50 D23:1
    r1
    0x8c,  r20x02xD0:50 D23:1
    c0
    :3122 c1:3122 c2:0d
    r1
    0x8c,  r20x02xD0:50 D23:1
    r1
    0x8c,  r20x02xD0:50 D23:1
    r1
    0x8c,  r20x02xD0:50 D23:

    Any ideas why I'm reading the wrong data would be a great help!


    Miller

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    25,022
    Is the top row on the breadboard connected to GND?

  3. #3
    Junior Member
    Join Date
    Feb 2014
    Location
    Vancouver WA
    Posts
    10
    Yeah, it's off to the left of the photo but I'd expect the isolation chip not to work at all if I missed that one...

    If you look at the analyzer trace the SPI signals correctly make it across the isolation barrier and back just delayed a tad,, By the time
    the clock rises, all is good..

    If I ran the 4MHz clock of the default SPI it was sometimes missing a clock edge, 2.oMHz would work fine but since I'm
    stuck at reading the wrong data it's kinda moot.

    Mil
    Last edited by milhead; 03-22-2014 at 10:53 PM.

  4. #4
    Have you tried to get it working without the iCoupler in the mix?

  5. #5
    Junior Member
    Join Date
    Feb 2014
    Location
    Vancouver WA
    Posts
    10
    I've made some headway... I've found a defect in my SPI bit-banging code and found that the SPI library code will run well at 1 MHz...
    The isolation chip is definitely forcing the slow SPI clock.. Stay tuned...

  6. #6
    Junior Member
    Join Date
    Feb 2014
    Location
    Vancouver WA
    Posts
    10
    Correct Bit Bang Transfer..

    PHP Code:
    #ifdef BANG_SPI
    char spiBangTransfer(char SPIDataOut)
    {
        
    unsigned char SPICount;                               // Counter used to clock out the data
        
    unsigned char SPIDataIn 0;

        
    digitalWrite(BSCK,LOW);
        
        for (
    SPICount 0SPICount 8SPICount++)
        {
            
    digitalWrite(BMOSI, (SPIDataOut 0x80));            // set Output bit
            
    digitalWrite(BSCKHIGH);                            // Clock Rising Edge
            
    SPIDataIn = (SPIDataIn <<= 1) | (digitalRead(BMISO) & 1);
            
    digitalWrite(BSCKLOW);
            
    SPIDataOut <<= 1;
        }                                        
        
    digitalWrite(BMOSI,LOW);              
        
        return (
    SPIDataIn);                      
    }
    #endif 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •