I'm using an Arduino Mega to control a CS1237 ADC. I'm sending a signal to the clock pin and after each clock pulse, waiting 1ms and then reading the response, according to the datasheet I found (via https://github.com/SiBangkotan/CS1237-ADC-cpp-library). This seems to be working in some capacity, because when I do Serial.println()
for each bit received, and for the resulting dataword, I get a 24 bit dataword that matches the 24 separate bits I got. However, when I take out the extra debugging uses of Serial.println()
that print each bit as they are received, I get a different dataword as well. It's 20 bits of all 1's every single time, instead of 24 bits of various 1's and 0s. I cant figure out why this extra debugging output in the serial communication channel should change the dataword that comes into the serial monitor?
Here's my setup and pre-setup code:
// Using pins 2 and 3 on the Arduino, since 0 and 1 are used to talk to the USB port.
int ndrdy = 2;
int clck = 3;
// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// make the drdy's pin an input and clock an output:
pinMode(ndrdy, INPUT);
}
Here's the relevant code:
void loop() {
// Hacky way of waiting for the signal that !DRDY is ready.
while(digitalRead(ndrdy) == LOW) {
// do nothing until pin pulls high.
}
while(digitalRead(ndrdy) == HIGH) {
// keep doing nothing until pin goes low again.
}
// now data is ready, we can read
long dataword = 0;
for(int i = 0; i < 24; i++) {
digitalWrite(clck, HIGH);
delayMicroseconds(1);
digitalWrite(clck, LOW);
int new_bit = digitalRead(ndrdy);
dataword <<= 1; // shift everything one place to the left
dataword |= new_bit; // add the new bit to the newly empty place
}
// There's a total of 27 bits but we don't care about the last 3.
// Write HIGH 3 times to flush it out.
for (int i = 0; i < 3; i++) {
digitalWrite(clck, HIGH);
delayMicroseconds(1);
digitalWrite(clck, LOW);
}
// Send out the data to the USB serial out:
Serial.println(dataword, BIN);
}
The output of this in serial monitor is
13:44:45.685 -> 11111111111111111111
13:44:45.685 -> 11111111111111111111
13:44:45.718 -> 11111111111111111111
13:44:45.751 -> 11111111111111111111
13:44:45.751 -> 11111111111111111111
13:44:45.785 -> 11111111111111111111
13:44:45.818 -> 111111111111111111111
13:44:45.852 -> 11111111111111111111
13:44:45.852 -> 11111111111111111111
13:44:45.885 -> 11111111111111111111
13:44:45.918 -> 111111111111111111111
13:44:45.918 -> 11111111111111111111
13:44:45.951 -> 11111111111111111111
...and so forth. However, when I add an extra Serial.println(new_bit);
just before the closing bracket of the for(int i = 0; i < 24; i++)
loop, I get output like this in the Arduino IDE's serial monitor (shown with timestamps turned on):
14:41:19.992 -> 0
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 1
14:41:19.992 -> 0
14:41:19.992 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 0
14:41:20.025 -> 0
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.025 -> 1
14:41:20.058 -> 0
14:41:20.058 -> 1
14:41:20.058 -> 11111111011111001111101
14:41:20.091 -> 0
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 1
14:41:20.091 -> 0
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 0
14:41:20.125 -> 0
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.125 -> 1
14:41:20.158 -> 1
14:41:20.158 -> 0
14:41:20.158 -> 1
14:41:20.158 -> 11111111011111001111101
This doesn't happen if I'm Serial.println()
-ing anything other than the new_bit
on that line, eg if I do Serial.println(dataword);
or if I introduce a small delay instead of doing the serial print. In those cases, it still does the twenty 1's output. I can't figure out what is wrong with the serial communication, since it seems like reading from the ADC is going OK. If I introduce a delay of 5000us or more, then there is a change in the contents of dataword
, which seems to then become a function of the length of the delay. I.e. the content of dataword
is constant for each delay length (5000us, 6000us, 10000us, and 20000us are what I tried). If the delay is long enough, it goes back to being all 1's.
clck
signal you usedelayMicroseconds(1)
and adigitalRead
as timing. The last 3 bits are missing a timing for the LOW phase of clck.Is that OK and as intended? – datafiddlerSerial.println(new_bit);
to has no effect; it's the same as if there is nothing there. Changing theSerial.println(new_bit);
toSerial.println(new_bit);
is the same as just deleting that line. @datafiddler it shouldn't matter how fast theclck
signal is sent as long as I don't send another until after I read the data from the first one, AFAICT. This 1us delay puts me inside the max clock speed in the datasheet. – the_pie_in_the_sky_is_a_lieSerial.println(new_bit);
todelayMicroseconds(1);
and it was the same as if I'd simply deletedSerial.println(new_bit);
and not replaced with anything. – the_pie_in_the_sky_is_a_lie