Hello everyone, I have been very grateful to all the help I've received by reading through this forum, but I have run into a problem that I cannot figure out. For some background information, my project is creating a remote for controlling a B-17 turret (this is a senior design project in college).
I'm using an Arduino Uno R3 and I have a display (working, with a navigable menu), RF Module (working), and a CAN module (working). All these components are on a SPI bus (important later). However, to move the turret, I have a joystick. Since this project has some budget and they want the remote to last as long as possible, I got this joystick off DigiKey: Grayhill 67A-DF-3C-030C (datasheet). It's a hall-effect joystick that communicates over I2C.
I created a test file and it works great- I can read the position of the joystick reliably over the I2C bus (and it's fun to move around). However, when I added the joystick code to the rest of the code (with the display, RF module, and CAN module), the program hung/froze when I called Wire.readFrom().
After much digging (using my test file as a playground), I found that once I created a display, RF module, or CAN module object and initialized it, that's when the I2C stopped working. It didn't matter which one I initialized they all made the I2C bus stop working.
After some more digging, I narrowed the problem down to a while() loop in twi_readFrom() (part of the Wire library that does more of the heavy lifting). The while() loop essentially just waits for all the data to be read. However, it never exits the loop. I'm not entirely sure how I2C works, but it looks like while this loop is running, each time the Arduino gets I2C data, an interrupt runs in the background and stores the data. Once the data transfer is complete, it sets a variable to exit that while() loop. This makes me think that the Arduino is never receiving the data.
Anyways, below is my test code and a snippet of the while() loop that it gets stuck in. Has anyone else run into this problem? Is it a problem with using the SPI and I2C busses at the same time? I'm using the default pins for both protocols. Any help would be appreciated!
My code (tft is the display, and radio is the RF module):
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <TFT_ILI9341.h>
#include <TFT_FastPin.h>
#include <turret_protocol.h>
#include <Wire.h>
#include <RF24.h>
int8_t joy_x, joy_y = 0;
TFT_ILI9341 tft = TFT_ILI9341();
//static RF24 radio(RADIO_CE_PIN,RADIO_CSN_PIN);
void setup()
{
//Wire.begin();
Serial.begin(115200);
tft.init();
//tft.setRotation(3);
/*
if(!radio.begin())
{
Serial.println("Radio not functional");
} else {
}
*/
}
void loop()
{
handle_joystick();
delay(500);
}
void handle_joystick()
{
if(true)
{
if(Wire.requestFrom(64, 2) == 0)
{
// error
}
else
{
joy_x = Wire.read();
joy_y = Wire.read();
// Handle X
if((joy_x & 0x80) != 0)
{
// Negative X
joy_x = joy_x - 255;
}
// Handle Y
if((joy_y & 0x80) != 0)
{
// Negative Y
joy_y = joy_y - 255;
}
Serial.print("Joystick X = ");
Serial.print(joy_x);
Serial.print(" / ");
Serial.print("Joystick Y = ");
Serial.println(joy_y);
}
}
}
And here is the while() loop that it gets stuck in (in twi_readFrom() function in twi.c):
// wait for read operation to complete
startMicros = micros();
while(TWI_MRX == twi_state){
if((twi_timeout_us > 0ul) && ((micros() - startMicros) > twi_timeout_us)) {
twi_handleTimeout(twi_do_reset_on_timeout);
return 0;
}
}