Hi,
I'm currently using an Arduino Fio and attempting to communicate with an ADC over I2C. When I run my code, it hangs at Wire.endTransmission() in the setup. However, I noticed that when I shook the FTDI cable, it stopped hanging, and I was able to get conversion results. My FTDI cable is fitted with male header pins and is put directly into the holes on the Fio.
Is there any way I can get the entire setup to be done smoothly? I have tried using an alternative I2C library (DssCircuits.com is for sale | HugeDomains), and obtained the same results. I also tried sending each byte in a Wire.write command, instead of all together in an array. I also tried casting the message as a byte array (i.e. Wire.write((uint8_t*)&adc_setup, 3)), but to no avail.
Interestingly, the Wire.endTransmission(adc_stop) in the loop does not hang the program. adc_stop is a boolean false, used to prevent the sending of the stop signal. However, even when I try to do the same in setup, it still does not work.
Initially, I thought it was the hard reset button that did the trick. However, I am now quite sure it is not the hard reset button, as I held the FTDI cable firmly against the Fio and pressed the reset button - it only restarted the sketch (which still froze). I suppose that the first few times when I pressed the reset button it jiggled the FTDI cable slightly.
And yes, my Fio was turned on.
Any advice would be much appreciated!
#include <I2C.h>
#include <Wire.h>
const byte adc_address = B0100000; // I2C Address of ADC Chip
const byte adc_config_add = B00000010; // Internal address of configuration register
const byte adc_conver_add = B01110000; // Address pointer for conversion result register in command mode
const byte adc_config_MSB = B00001111; // Most significant byte of configuration register, select channels 8 to 5
const byte adc_config_LSB = B11111011; // Least significant byte of configuration register, select channels 4 to 1
// Enable filtering on SDA/SCL lines, busy output, and active high for busy pin
const boolean adc_stop = false; // Stop parameter for endTransmission that sends a restart and keeps connection active
byte adc_setup[] = {byte(adc_config_add), byte(adc_config_MSB), byte(adc_config_LSB)}; // Array to store setup data to write to ADC
//byte adc_setup[] = {byte(adc_config_MSB), byte(adc_config_LSB)}; // Array to store setup data to write to ADC configuration register
unsigned int adc_data[10]; // Array to store ADC values for 10 bits (8 channels)
int soft_reset_count = 0;
void setup() {
//Start Serial port
Serial.begin(9600); // start serial for output
Serial.println("Serial port has been opened");
//Send settings to ADC I2C device
Wire.begin(); // Join i2c bus (address optional for master)
I2c.pullup(0); // Disable internal pullups
Wire.beginTransmission(adc_address); // Transmit to ADC
Serial.println("Transmission to ADC has been initiated");
Wire.write(adc_setup, 3); // Send config options
Wire.write((uint8_t*)&adc_setup, 3); // Send config options
for (int i = 0; i < 3; i++) {
Serial.println(adc_setup[i], BIN); // Display configuration register address and messages sent
}
// Wire.write(byte(adc_config_add)); // Send configuration register address and messages as separate bytes
// Wire.write(byte(adc_config_MSB));
// Wire.write(byte(adc_config_add));
Serial.println("Wire.write of configuration data has been executed");
Wire.endTransmission(adc_stop); // Stop transmitting
// I2c.write(byte(adc_address), byte(adc_config_add), (uint8_t*)&adc_setup, 2); // Use alternate I2c library to configure ADC
Serial.println("ADC has been configured");
}
void loop() {
get_adc(); // read data from adc
// Test print data received from ADC
for (int i = 0; i < 10; i++)
{
Serial.print(adc_data[i], BIN); // print the character in binary
Serial.print(","); // print comma
}
Serial.println(""); // print carriage return
delay(500);
}
// Function to get data from ADC
void get_adc() {
unsigned char hi_lo_byte; // Keep track of high or low byte, 1 for high byte, 0 for low byte
hi_lo_byte = 1; // First byte will be a high byte
unsigned char data_values_rcvd = 0; // keep track of how many chars received
unsigned char adc_buffer;
Wire.beginTransmission(adc_address); // Transmit to ADC
Wire.write(adc_conver_add); // Write to address pointer to read from conversion result register in command mode
Wire.endTransmission(adc_stop); // Transmit bytes queued by byte() and issue restart so connection remains active
Serial.println("Conversion result register address sent");
while (Wire.available()) {
if (hi_lo_byte) { // Its a high byte
adc_buffer = Wire.read() << 8; // receive high byte and shift left 8
// Extract MSB to B6 of sample and put in data array in position dependent on channel
adc_data[0] += (B1 & (adc_buffer >> 3)) >> data_values_rcvd;
adc_data[1] += (B1 & (adc_buffer >> 2)) >> data_values_rcvd;
adc_data[2] += (B1 & (adc_buffer >> 1)) >> data_values_rcvd;
adc_data[3] += (B1 & (adc_buffer)) >> data_values_rcvd;
hi_lo_byte = 0; // next byte will be a low byte
}
else {
adc_buffer = Wire.read(); // receive low byte
// Extract B5 to B0 of sample and put in data array in position dependent on channel
adc_data[4] += (B1 & (adc_buffer >> 7)) >> data_values_rcvd;
adc_data[5] += (B1 & (adc_buffer >> 6)) >> data_values_rcvd;
adc_data[6] += (B1 & (adc_buffer >> 5)) >> data_values_rcvd;
adc_data[7] += (B1 & (adc_buffer >> 4)) >> data_values_rcvd;
adc_data[8] += (B1 & (adc_buffer >> 3)) >> data_values_rcvd;
adc_data[9] += (B1 & (adc_buffer >> 2)) >> data_values_rcvd;
data_values_rcvd++; // Increase counter for number of channels that have been read from
hi_lo_byte = 1; // next byte will be a high byte
}
}
}
void software_Reset() // Restarts program from beginning but does not reset the peripherals and registers
{
asm volatile (" jmp 0");
}