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.
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
Full Source:
Gives the output...
Any ideas why I'm reading the wrong data would be a great help!
Miller
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.
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
Full Source:
PHP:
// 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(greenLedPin, OUTPUT);
pinMode(redLedPin, OUTPUT);
pinMode(adcCS, OUTPUT);
pinMode(otherCS, OUTPUT);
pinMode(0, INPUT);
digitalWrite(otherCS, HIGH);
digitalWrite(adcCS, HIGH);
#ifdef BANG_SPI
pinMode(BSCK, OUTPUT);
pinMode(BMOSI, OUTPUT);
pinMode(BMISO, INPUT_PULLUP);
digitalWrite(BSCK, LOW);
digitalWrite(BMOSI, LOW);
#endif
digitalWrite(redLedPin, HIGH);
digitalWrite(greenLedPin, HIGH);
Serial.begin(38400);
#ifndef BANG_SPI
// start the SPI library:
SPI.begin();
#endif
}
void report(int count)
{
double v, a;
char buf[128];
v = cos((double)count / 100)*4.5;
a = cos((double)count / 120)*3.5;
sprintf(buf, "v:%15.6lf a:%15.6lf c:%d\n", v, a, count);
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 = 0; SPICount < 8; SPICount++)
{
digitalWrite(BMOSI, (SPIDataOut & 0x80)); // set Output bit
digitalWrite(BSCK, HIGH); // Clock Rising Edge
SPIDataIn += (digitalRead(BMISO)&1); // Read the data bit
digitalWrite(BSCK, LOW);
SPIDataOut <<= 1;
SPIDataIn <<= 1;
}
digitalWrite(BMOSI,LOW);
return (SPIDataIn);
}
#endif
int16_t readAdcChannel(int channel)
{
char cmd2;
char cmd1 = 0x18 + channel;
char r1, r2;
uint16_t res;
cmd2 = cmd1 << 7;
cmd1 = cmd1 >> 1;
digitalWrite(adcCS, LOW);
transfer(cmd1);
r1 = transfer(cmd2);
r2 = transfer(0);
digitalWrite(adcCS, HIGH);
digitalWrite(otherCS, LOW);
transfer(r1);
transfer(r2);
digitalWrite(otherCS, HIGH);
sprintf(bbuf, "r1: 0x%02x, r2: 0x02x, D0:%d D23:%d", r1, r2, (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(greenLedPin, ledState); // 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:
r1: 0x8c, r2: 0x02x, D0:48 D23:1
r1: 0x8c, r2: 0x02x, D0:48 D23:1
r1: 0x8c, r2: 0x02x, D0:50 D23:1
c0:3120 c1:3120 c2:0d
r1: 0x8c, r2: 0x02x, D0:50 D23:1
r1: 0x8c, r2: 0x02x, D0:50 D23:1
r1: 0x8c, r2: 0x02x, D0:50 D23:1
c0:3122 c1:3122 c2:0d
r1: 0x8c, r2: 0x02x, D0:50 D23:1
r1: 0x8c, r2: 0x02x, D0:50 D23:1
r1: 0x8c, r2: 0x02x, D0:50 D23:1
Any ideas why I'm reading the wrong data would be a great help!
Miller