save data every 3 second and send an array every 5 minutes - arduino

I got an MPU connected to a wemos d1 mini. The sensor send 3 values: X,Y and Z axis. Since my project is solar powered I need to reduce power consumption. In order to do so I want to read the 3 values of the MPU every 3 seconds, store the values in an array and after 5 minutes of sampling power up the wifi and send the array via mqtt to my topic.
I've already tested every part of my code and everything works.
For example if I try to send an array of three objects it works perfectly
But when I try to send an array of 100 objects it doesn't work.
(Note: Where the above "100" come from? If I need to send data every 5 minutes and I read values every 3 seconds here I have 100 samplings)
Hope someone could help
unsigned long t_start;
void setup()
{
t_start = millis();
}
//compute the required size
const size_t CAPACITY = JSON_ARRAY_SIZE(100) + 100 * JSON_OBJECT_SIZE(3);
//allocate the memory for the document
StaticJsonDocument<CAPACITY> doc;
//MPU
const int MPU = 0x68; // I2C address of the MPU-6050
int16_t AcX, AcY, AcZ;
void loop()
{
//Create an empty array
JsonArray arr = doc.to<JsonArray>();
if (millis() - t_start >= 3000) {
for (int i = 0; i < 100; i++) {
//MPU reading
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Create a JSON Object
JsonObject obj = doc.createNestedObject();
obj["AcX"] = AcX;
obj["AcY"] = AcY;
obj["AcZ"] = AcZ;
}
t_start = millis();
}
}
//MQTT PUBLISHING JSON PACKAGE
char mqttData[MQTT_BUFFER];
serializeJson(doc, mqttData);
Serial.println(mqttData);
int ret = client.publish("esp8266/JSON", mqttData);
} //end of loop

If you want one measure every three seconds instead of 100 measures every 3 seconds, the code should look like this:
#define MQTT_KEEPALIVE 300
// headers ...
// setup() ...
void loop() {
//Create an empty array
JsonArray arr = doc.to<JsonArray>();
static auto t_start = millis(); // static will preserve last value even after exiting loop
int8_t count = 0;
while (count < 100) { // stays here whole 300s, so if the keep alives are needed or doing something else, it should be inside too
client.loop(); // sugested in comments
if (millis() - t_start >= 3000) {
t_start += 3000;
++count;
//MPU reading
Wire.beginTransmission(MPU);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 14, true); // request a total of 14 registers
AcX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
//Create a JSON Object
JsonObject obj = doc.createNestedObject();
obj["AcX"] = AcX;
obj["AcY"] = AcY;
obj["AcZ"] = AcZ;
}
// handling keep alives every X seconds as it's unlikely as long as 300s:
// if (...) sendKeepAlive();
}
// after 100 measures it'll get here:
//MQTT PUBLISHING JSON PACKAGE
char mqttData[MQTT_BUFFER];
serializeJson(doc, mqttData);
Serial.println(mqttData);
int ret = client.publish("esp8266/JSON", mqttData);
} //end of loop
However it should solve just most obvious issue with the code only. There might be others, like buffers might be too small, or so...
And it's untested, I don't have this HW setup

Related

Send char array to queue on ESP32 FreeRTOS Arduino IDE

I am a beginner making a program for ESP32 using Arduino IDE.
My code works with 2 tasks, each one running in one core simultaneously.
Task1 runnning on core 0 collects data from various GPIO (ADC, Digital and PWM) and generate 2 char arrays that i need to send to the queue.
Task2 running on core 1 receives CANBUS data from a MCP2515 IC (through SPI) and print this data to serial #1Mbps baud.
I need task2 also to receive the 2 char arrays sent to the queue by task1 and print them also in serial, so that task2 will print its own data and also the queue data in serial, without "colliding" data.
Task1 generates around 200 messages/sec.
Task2 generates around 1,500~2,000 messages/sec.
These messages are in CANBUS frame fashion, around 25 to 35 chars each. (Not int, but numbers, letters, comma...).
I've read the FreeRTOS documentation about queues, but given my lack of experience i have no idea how to deal in this case, because i am not queuing INT, but char arrays generated by task1.
Before i was working with semaphores but it turns out that there is loss of messages, as while one task is running and blocks the other, data from CANBUS should arrive and will be lost, and vice-versa.
Below is my entire code. If someone could give me some light, i appreciate.
Thanks!
#include <mcp2515.h>
#include "PWM.hpp"
#include <SPI.h>
#include <movingAvg.h>
movingAvg avgsensorV1(8);
movingAvg avgsensorV2(8);
movingAvg avgsensorV3(8);
movingAvg avgsensorV4(8);
//declare tasks
TaskHandle_t Task1;
TaskHandle_t Task2;
//setup of Arduino pins
int V1 = 35;
int V2 = 34;
int V3 = 36;
int V4 = 39;
int sensorD1 = 17;
int sensorD2 = 16;
int sensorD3 = 27;
PWM my_pwm(25); //define PWM pin reading with interrupt
int pwm_out = 13;
int ADCoffset = 130; //defines the offset on ADC readings due to AREF offset
//PWM generation properties
int freq = 500;
int ledChannel = 0;
int resolution = 12;
//preparation of MCP2515
struct can_frame canMsg;
int CAN_message_delay = 8; //delay after sending each CAN message - use to reach the desired fps
MCP2515 mcp2515(5); //define CS pin for MCP2515 on pin 5
void setup() {
//start average routines
avgsensorV1.begin();
avgsensorV2.begin();
avgsensorV3.begin();
avgsensorV4.begin();
//create task1 for sensors data collection
xTaskCreatePinnedToCore(Sensors,"Task1",2048,NULL,1,&Task1,0);
delay(500);
//create task2 for CANBUS data collection
xTaskCreatePinnedToCore(CAN,"Task2",2048,NULL,1,&Task2,1);
delay(500);
Serial.begin(1000000); //Initialize serial
analogReadResolution(12); //define ADC resolution
my_pwm.begin(true); // initialize PWM function
//define GPIO modes
pinMode(sensorD1, INPUT);
pinMode(sensorD2, INPUT);
pinMode(sensorD3, INPUT);
pinMode(V1, INPUT);
pinMode(V2, INPUT);
pinMode(V3, INPUT);
pinMode(V4, INPUT);
pinMode(25, INPUT);
//MCP2515 definitions
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS, MCP_16MHZ); //set CAN speed 500kbps and MCP2515 xtal 16MHz
mcp2515.setNormalMode();
}
// Task1 on core 0 - read analog/digital sensors values and send to queue
void Sensors( void * pvParameters ){
for(;;){
//read 4 analog values and take averages
int sensorV1 = (analogRead(V1) * (3300.0 / 4095.0) + ADCoffset);
int vavgsensorV1 = avgsensorV1.reading(sensorV1);
int sensorV2 = (analogRead(V2) * (3300.0 / 4095.0) + ADCoffset);
int vavgsensorV2 = avgsensorV2.reading(sensorV2);
int sensorV3 = (analogRead(V3) * (3300.0 / 4095.0) + ADCoffset);
int vavgsensorV3 = avgsensorV3.reading(sensorV3);
int sensorV4 = (analogRead(V4) * (3300.0 / 4095.0) + ADCoffset);
int vavgsensorV4 = avgsensorV4.reading(sensorV4);
//convert 16bit analog values into 2 bytes MSB & LSB
byte sensorV1B = (vavgsensorV1 & 0x00FF);
byte sensorV1A = ((vavgsensorV1 & 0xFF00) >>8);
byte sensorV2B = (vavgsensorV2 & 0x00FF);
byte sensorV2A = ((vavgsensorV2 & 0xFF00) >>8);
byte sensorV3B = (vavgsensorV3 & 0x00FF);
byte sensorV3A = ((vavgsensorV3 & 0xFF00) >>8);
byte sensorV4B = (vavgsensorV4 & 0x00FF);
byte sensorV4A = ((vavgsensorV4 & 0xFF00) >>8);
//send task1 message 1 to queue
char CAN1[31];
sprintf(CAN1, "%d,1,8,%02x%02x%02x%02x%02x%02x%02x%02x", micros(), sensorV1A, sensorV1B, sensorV2A, sensorV2B, sensorV3A, sensorV3B, sensorV4A, sensorV4B);
???????????;
//read 3 digital sensors values
int vsensorD1 = digitalRead(sensorD1);
int vsensorD2 = digitalRead(sensorD2);
int vsensorD3 = digitalRead(sensorD3);
//read PWM value
uint16_t PWM_value = (my_pwm.getValue());
//convert 16bit PWM value into 2 bytes MSB & LSB
byte PWM_B = (PWM_value & 0x00FF);
byte PWM_A = ((PWM_value & 0xFF00) >>8);
//send task1 message 2 to queue
char CAN2[25];
sprintf(CAN2, "%d,2,5,%02x%02x%02x%02x%02x", micros(), vsensorD1, vsensorD2, vsensorD3, PWM_A, PWM_B);
???????????;
delay(CAN_message_delay);
}
}
// Task2 on core 1 - receive CANBUS data from MCP2515 and print to serial + receive messages from queue and print to serial too
void CAN( void * pvParameters ){
for(;;){
if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK) {
Serial.print(micros());
Serial.print(",");
Serial.print(canMsg.can_id, HEX); // print ID
Serial.print(",");
Serial.print(canMsg.can_dlc, HEX); // print DLC
Serial.print(",");
for (int i = 0; i<canMsg.can_dlc; i++) { // print the data
Serial.print(canMsg.data[i],HEX);
}
Serial.println();
}
}
}
void loop() {
}

Arduino USB serial connection to Raspberry Pi (Rasbian) not initializing

I have an Arduino Nano 33 iot that outputs data via Serial at 38400 baud, connected via USB. Setup starts with Serial.Begin. The Raspberry Pi 4, running Raspian buster is set up to receive the data. It can see the correct port, /dev/ttyACM0, but nothing comes in.
I even installed the correct Arduino IDE and SAMD board package on the Raspberry Pi. It still does not find it until after the IDE uploads the replacement sketch and the CPU is reset. The IDE can grab the serial number and board type though. I can then exit out of the IDE and the Arduino is still pumping out serial to the Raspberry Pi.
The only other way to make it work is by pressing the reset button on the Arduino every time a reboot is done on the Raspberry Pi. Serial was tested on the Pi using screen.
Neither of these options are convenient. What am I missing?
/*
Connects via I2C to a CMPS14, outputs NMEA0183 HDM sentences via Serial (38400 baud)
By James Henderson, 2014, adapted to output NMEA sentences by Ian Van Schaick
*/
#include <Keyboard.h>
#include <Wire.h>
#define CMPS14_ADDRESS 0x60 // Address of CMPS14 shifted right one bit for arduino wire library
#define ANGLE_8 1 // Register to read 8bit angle from
unsigned char high_byte, low_byte, angle8;
signed char pitch, roll;
float angle16;
int fine;
float bearingH; // Holds whole degrees of bearing
float bearingL; // Holds decimal digits of bearing
int bearing;
char nbsp;
char mystring[25];
char mystring2[25];
char mystring3[25];
int software;
int cal;
unsigned int _last_status;
uint8_t checksum(char *s)
{
uint8_t c = 0;
while (*s)
c ^= *s++;
return c;
}
void CMPS14_eraseProfil()
{
Wire.beginTransmission(CMPS14_ADDRESS);
Wire.write(0x00);
Wire.write(0xE0);
_last_status = Wire.endTransmission();
delay(20); // 20ms delay after each of the three bytes send
Wire.beginTransmission(CMPS14_ADDRESS);
Wire.write(0x00);
Wire.write(0xE5);
_last_status = Wire.endTransmission();
delay(20); // 20ms delay after each of the three bytes send
Wire.beginTransmission(CMPS14_ADDRESS);
Wire.write(0x00);
Wire.write(0xE2);
_last_status = Wire.endTransmission();
delay(20); // 20ms delay after each of the three bytes send
}
//Correct heading for known deviation
int DeviationCorrect(int Head)
{
return 0;
}
void setup() {
Serial.begin(38400); // Start serial port
Wire.begin();
nbsp = 32;
// CMPS14_eraseProfil();
}
void loop() {
Wire.beginTransmission(CMPS14_ADDRESS); //starts communication with CMPS14
Wire.write(ANGLE_8); //Sends the register we wish to start reading from
Wire.endTransmission();
// Request 5 bytes from the CMPS14
// this will give us the 8 bit bearing,
// both bytes of the 16 bit bearing, pitch and roll
Wire.requestFrom(CMPS14_ADDRESS, 26);
while (Wire.available() < 26); // Wait for all bytes to come back
// software = Wire.read();
// Serial.print("Version: ");
// Serial.println(software);
angle8 = Wire.read(); // Read back the 5 bytes
high_byte = Wire.read();
low_byte = Wire.read();
pitch = Wire.read();
roll = Wire.read();
// int i = 6;
// while (i <= 25) {
// Wire.read();
// i++;
// }
//
// cal = Wire.read();
// Serial.print("Cal: ");
// Serial.println(cal);
bearing = ((high_byte << 8) + low_byte) / 10;
fine = ((high_byte << 8) + low_byte) % 10;
byte data[128] = "$HCHDM,";
data[8] = bearing;
// int deviation = 0;
//DeviationCorrect(bearing);
// bearing = bearing;
//+ deviation;
//Print out NMEA 0183 string HDM
snprintf(mystring, sizeof(mystring), "$HCHDM,%d.%d,M", bearing , fine);
uint8_t crc = checksum(mystring + 1);
Serial.print(mystring);
Serial.print("*");
if (crc < 16) Serial.print("0");
Serial.println(crc, HEX);
//Print out NMEA 0183 string XDR for Pitch
snprintf(mystring2, sizeof(mystring2), "$HCXDR,A,%d,D,PITCH", pitch);
uint8_t crc2 = checksum(mystring2 + 1);
Serial.print(mystring2);
Serial.print("*");
if(crc2 < 16) Serial.print("0");
Serial.println(crc2, HEX);
//Print out NMEA 0183 string XDR for Roll/Heel
snprintf(mystring3, sizeof(mystring3), "$HCXDR,A,%d,D,ROLL", roll);
uint8_t crc3 = checksum(mystring3 + 1);
Serial.print(mystring3);
Serial.print("*");
if(crc3 < 16) Serial.print("0");
Serial.println(crc3, HEX);
delay(100);
}

How to know Arduino Sampling Rate

/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.
*/
#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft
#include <FFT.h> // include the library
unsigned long time;
void setup() {
Serial.begin(115200); // use the serial port
TIMSK0 = 0; // turn off timer0 for lower jitter
ADCSRA = 0xe5; // set the adc to free running mode
ADMUX = 0x40; // use adc0
DIDR0 = 0x01; // turn off the digital input for adc0
}
void loop() {
while(1) { // reduces jitter
cli(); // UDRE interrupt slows this way down on arduino1.0
for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
while(!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fft_input[i] = k; // put real data into even bins
Serial.print("input ");
Serial.print(i);
Seirla.print(" = ");
Serial.println(k);
fft_input[i+1] = 0; // set odd bins to 0
}
fft_window(); // window the data for better frequency response
fft_reorder(); // reorder the data before doing the fft
fft_run(); // process the data in the fft
fft_mag_log(); // take the output of the fft
sei();
Serial.println("start");
for (byte i = 0 ; i < FFT_N/2 ; i++) {
Serial.print("\t output");
Serial.print(i);
Serial.println(fft_log_out[i]); // send out the data
}
}
}
Im using this FFT example code for FFT
cli(); // UDRE interrupt slows this way down on arduino1.0
for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
while(!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fft_input[i] = k; // put real data into even bins
Serial.print("input ");
Serial.print(i);
Seirla.print(" = ");
Serial.println(k);
fft_input[i+1] = 0; // set odd bins to 0
}
in this input part How much input time period?
Theres no delay(); function in this example
while(!(ADCSRA & 0x10)); // wait for adc to be ready
this line work like delay() function? and this function how long wait for Analog0?
The sample rate is set in wiring.c:
https://code.google.com/p/arduino/source/browse/trunk/hardware/cores/arduino/wiring.c?r=565#210
So on an 16mHz arduino has a maximum sample rate of at 9600hz, but the real sample rate highly depends on on the delay you have between conversions.
As your baud rate is pretty high and you don't do a lot of calculation it should somehow be next to 9600hz.
update:
there's a more accurate answer here: https://arduino.stackexchange.com/a/701

arduino 2 bytes serial.read

I am beginer in programming, and I need some help to read 2 bytes (msb/lsb) that comes after a request (0x01 to msb and 0x02 to lsb) via serial, and then, make an mathematical operation and display on an 2x16 display. I have the functions of my project that use only 1 byte working good. One example:
void funcao4()
{
int MAP;
float MAP1;
delay(600);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("MAP[mmHG]");
Serial.write(0x06); //request
if (Serial.available() > 0)
{
MAP = Serial.read() ; //read
MAP1 = (MAP * 2.8759 + 91); //operation
lcd.setCursor(0,1);
lcd.print(MAP1); //display
}
}
regards.
Wait until the Serial buffer has two bytes, then read them:
void funcao4()
{
int MAP;
float MAP1;
delay(600);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("MAP[mmHG]");
Serial.write(0x06); //request
while(Serial.available() < 2); //wait until there are two bytes in the buffer
MAP = Serial.read() << 8 ; //read MSB into MAP
MAP += Serial.read(); //read LSB into MAP
MAP1 = (MAP * 2.8759 + 91); //operation
lcd.setCursor(0,1);
lcd.print(MAP1); //display
}
This code is blocking so you may want to change from a while loop to a delay and some if statements. Also I'm not sure if your LCD prints MSB or LSB first, I assumed MSB.
if (Serial.available() >= 2)
{
MAP = Serial.read() << 8;
MAP |= Serial.read();
}

Arduino Code not executing after Wire.endTransmission line

I am working on a project, syncing Nintendo Nunchuk with Arduino. I found a code online for the same from http://letsmakerobots.com/node/5684
Here, is the code
#include <Wire.h>;
void setup(){
Serial.begin(19200);
nunchuck_setpowerpins();
nunchuck_init();
Serial.print("Nunchuck ready\n");
}
void loop(){
nunchuck_get_data();
nunchuck_print_data();
delay(1000);
}
//======================================================================================================================================================================================================//
//Do not modify!!!!!!!!
//======================================================================================================================================================================================================//
//
// Nunchuck functions
//
static uint8_t nunchuck_buf[6]; // array to store nunchuck data,
// Uses port C (analog in) pins as power & ground for Nunchuck
static void nunchuck_setpowerpins()
{
#define pwrpin PORTC3
#define gndpin PORTC2
DDRC |= _BV(pwrpin) | _BV(gndpin);
PORTC &=~ _BV(gndpin);
PORTC |= _BV(pwrpin);
delay(100); // wait for things to stabilize
}
// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
Wire.begin(); // join i2c bus as master
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x40); // sends memory address
Wire.send(0x00); // sends sent a zero.
Wire.endTransmission(); // stop transmitting
}
// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
}
// Receive data back from the nunchuck,
// returns 1 on successful read. returns 0 on failure
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6); // request data from nunchuck
while (Wire.available ()) {
// receive byte as an integer
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request(); // send request for next data payload
// If we recieved the 6 bytes, then go print them
if (cnt >= 5) {
return 1; // success
}
return 0; //failure
}
// Print the input data we have recieved
// accel data is 10 bits long
// so we read 8 bits, then we have to add
// on the last 2 bits. That is why I
// multiply them by 2 * 2
void nunchuck_print_data()
{
static int i=0;
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
int accel_x_axis = nunchuck_buf[2]; // * 2 * 2;
int accel_y_axis = nunchuck_buf[3]; // * 2 * 2;
int accel_z_axis = nunchuck_buf[4]; // * 2 * 2;
int z_button = 0;
int c_button = 0;
// byte nunchuck_buf[5] contains bits for z and c buttons
// it also contains the least significant bits for the accelerometer data
// so we have to check each bit of byte outbuf[5]
if ((nunchuck_buf[5] >> 0) & 1)
z_button = 1;
if ((nunchuck_buf[5] >> 1) & 1)
c_button = 1;
if ((nunchuck_buf[5] >> 2) & 1)
accel_x_axis += 2;
if ((nunchuck_buf[5] >> 3) & 1)
accel_x_axis += 1;
if ((nunchuck_buf[5] >> 4) & 1)
accel_y_axis += 2;
if ((nunchuck_buf[5] >> 5) & 1)
accel_y_axis += 1;
if ((nunchuck_buf[5] >> 6) & 1)
accel_z_axis += 2;
if ((nunchuck_buf[5] >> 7) & 1)
accel_z_axis += 1;
Serial.print(i,DEC);
Serial.print("\t");
Serial.print("joy:");
Serial.print(joy_x_axis,DEC);
Serial.print(",");
Serial.print(joy_y_axis, DEC);
Serial.print(" \t");
Serial.print("acc:");
Serial.print(accel_x_axis, DEC);
Serial.print(",");
Serial.print(accel_y_axis, DEC);
Serial.print(",");
Serial.print(accel_z_axis, DEC);
Serial.print("\t");
Serial.print("but:");
Serial.print(z_button, DEC);
Serial.print(",");
Serial.print(c_button, DEC);
Serial.print("\r\n"); // newline
i++;
}
// Encode data to format that most wiimote drivers except
// only needed if you use one of the regular wiimote drivers
char nunchuk_decode_byte (char x)
{
x = (x ^ 0x17) + 0x17;
return x;
}
// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_zbutton()
{
return ((nunchuck_buf[5] >> 0) & 1) ? 0 : 1; // voodoo
}
// returns zbutton state: 1=pressed, 0=notpressed
int nunchuck_cbutton()
{
return ((nunchuck_buf[5] >> 1) & 1) ? 0 : 1; // voodoo
}
// returns value of x-axis joystick
int nunchuck_joyx()
{
return nunchuck_buf[0];
}
// returns value of y-axis joystick
int nunchuck_joyy()
{
return nunchuck_buf[1];
}
// returns value of x-axis accelerometer
int nunchuck_accelx()
{
return nunchuck_buf[2]; // FIXME: this leaves out 2-bits of the data
}
// returns value of y-axis accelerometer
int nunchuck_accely()
{
return nunchuck_buf[3]; // FIXME: this leaves out 2-bits of the data
}
// returns value of z-axis accelerometer
int nunchuck_accelz()
{
return nunchuck_buf[4]; // FIXME: this leaves out 2-bits of the data
}
When I write, Serial.Println("End"), in the line after Wire.endTransmission(); in function nunchuck_init(), it does not display on Serial Monitor.
Also, it does not display Nunchuck ready on Serial Monitor since it is written after nunchuck_init() has been called.
I am working on Arduino 0023, Windows 7.
A existing problem with the stock Arduino Wire library is that there is no timeout.
It is possible for the endTransmission function to hang the microcontroller in different scenarios.
This issue has been discussed in several other forums, and the best solution I've found so far is to use an alternate library.
The Arduino I2C Master Library by Wayne Truchsess
http://www.dsscircuits.com/index.php/articles/66-arduino-i2c-master-library
With proper timeout, it fixed the problem on my system reading the MMA7455 accelero
In the source code provided, there's an example where it shows how the same piece of program is done using Wire vs the I2C Master Library.
You can use that example to easily modify your code to adopt the new library.

Resources