I'm trying to execute following source on my RC transmitter and receiver which uses NRF24 module. Today i uploaded same sketch as i did half year ago and it stopped receiving any data from transmitter, nothing is printed in DEBUG_PRINT sections.
On transmitter NRF24 is connected to 7, 8.
On receiver NRF24 is connected to 9, 10.
Wiring checked 7 times, correct, power supply of the receiver is 7.4V to the VIN, power supply for the transmitter is USB source.
Running on the arduino nano.
Source for transmitter is:
// Flash for self-diy NRF24lo* transmiter controller.
// 6 buttons, 4-way sticks, based on CX-10c controller.
#include <EEPROM.h>
#include <SPI.h>
#include "RF24.h"
#define DEBUG_PRINT
// #define DEBUG_PRINT_RAW
#ifdef DEBUG_PRINT
#include <printf.h>
#endif
// IO mappings
#define STICK0 A3
#define STICK1 A2
#define STICK2 A0
#define STICK3 A1
#define BTN0 3
#define BTN1 6
#define BTN2 5
#define BTN3 4
#define BTN4 9
#define BTN5 A4
#define STLED 2
// Optional moddings
#define BTN_LONG_PRESS 1000
#define LED_ST_OFF 0
#define LED_ST_CONST 1
#define LED_ST_FLASH 2
#define LED_ST_FAST_FLASH 3
#define LED_ST_FLASH_TIME 250
#define LED_ST_FAST_FLASH_TIME 100
#define LED_POWER 150
// Package types
#define PACKAGE_STICKS 3
#define PACKAGE_BUTTON 5
#define PACKAGE_PING 7
#define PACKAGE_TIMEOUT 100
// Amount of packages should be dropped sequently to detect disconnect
#define TX_DROP_EDGE 16
// Long press stick 0 to start calibration, long press to stop
// Struct with min/max calibration values
struct STICK_CALIBRATION {
int stmx[4];
int stmn[4];
};
// Struct with info of button presses
struct BTN_STATE {
int press[6];
unsigned long time[6];
// Used in long press to avoid multiple pressing
int acted[6];
};
// Struct with state of flashing/idle/working LED
// FLASH --> CONST/OFF
// FAST_FLASH --> CONST/OFF
struct LED_STATE {
// Previous type (for FLASH return to OFF/CONST state)
int ptype;
// Type of operation
int type;
// ON/OFF
int state;
// Time since action
unsigned long time;
// Count of flashes
int count;
};
// Sender package type.
// Contains type and values for button or values for sticks
struct Package {
int type;
union {
struct {
int number;
int lpress;
int dummy[2];
} button;
struct {
int sticks[4];
} sticks;
} data;
};
// Info of sticks calibration
STICK_CALIBRATION calibration;
bool calibration_mode = 0;
int sticks[4];
// When entering lock mode, stick data is not updating from input
bool lock_mode = 0;
// info of buttons states
BTN_STATE buttons;
LED_STATE led_state;
// Use NRF24lo1 transmitter on pins 7, 8
RF24 radio(7, 8);
byte addresses[][6] = { "TRAAA", "REEEE" };
// Amount of sequently dropped packages. Used to detect disconnect
int tx_dropped = 0;
// Used to prevent longpress repeat
// On long press button could be used as sticky press function,
// to avoid button sticking and long press act once during while push down,
// use this function to mark button as acted
void btn_act(int nubmer);
// Called on button press/longpress
void btn_action(int number, int lpress);
// Set led ON/OFF with change of state flag
void led_set_state(int state);
// Set led action type (FLAST, CONST, e.t.c.)
void led_set(int type, int count);
// Sends single package with given amount of attempts.
// Allows waiting for responce of receiver. The response should be 0.
// Returns 1 on success, 0 on failture.
int send_package(byte* pack, int size);
void setup() {
#ifdef DEBUG_PRINT
Serial.begin(115200);
#endif
// Set up transmitter
radio.begin();
radio.setChannel(77);
radio.enableAckPayload();
radio.setPALevel(RF24_PA_MAX);
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1, addresses[0]);
#ifdef DEBUG_PRINT
printf_begin();
radio.printDetails();
#endif
// Read calibration values
byte* cal_struct = (byte*) &calibration;
for (int i = 0; i < sizeof(STICK_CALIBRATION); ++i)
cal_struct[i] = EEPROM.read(i);
#ifdef DEBUG_PRINT
Serial.println("CALIBRATION: ");
for (int i = 0; i < 4; ++i) {
Serial.print('(');
Serial.print(calibration.stmn[i]);
Serial.print(", ");
Serial.print(calibration.stmx[i]);
Serial.print(") ");
}
Serial.println();
#endif
buttons = {{0,0,0,0,0,0}, {0,0,0,0,0,0}, {0,0,0,0,0,0}};
// Clear LED state
led_state.ptype = 0;
led_state.type = 0;
led_state.state = 0;
led_state.time = 0;
led_state.count = 0;
// Prepare pinout
pinMode(STLED, OUTPUT);
pinMode(STICK0, INPUT_PULLUP);
pinMode(STICK1, INPUT_PULLUP);
pinMode(STICK2, INPUT_PULLUP);
pinMode(STICK3, INPUT_PULLUP);
pinMode(BTN0, INPUT_PULLUP);
pinMode(BTN1, INPUT_PULLUP);
pinMode(BTN2, INPUT_PULLUP);
pinMode(BTN3, INPUT_PULLUP);
pinMode(BTN4, INPUT_PULLUP);
pinMode(BTN5, INPUT_PULLUP);
}
void loop() {
// Read sticks & map to calibration
if (!lock_mode) {
sticks[0] = analogRead(STICK0);
sticks[1] = analogRead(STICK1);
sticks[2] = 1024 - analogRead(STICK2);
sticks[3] = 1024 - analogRead(STICK3);
}
// Read stick buttons
int rbtn[6];
rbtn[0] = !digitalRead(BTN0);
rbtn[1] = !digitalRead(BTN1);
// read optional buttons
rbtn[2] = !digitalRead(BTN2);
rbtn[3] = !digitalRead(BTN3);
rbtn[4] = !digitalRead(BTN4);
rbtn[5] = !digitalRead(BTN5);
#ifdef DEBUG_PRINT
#ifdef DEBUG_PRINT_RAW
// Debug out
Serial.print(sticks[0]); Serial.print(' ');
Serial.print(sticks[1]); Serial.print(' ');
Serial.print(sticks[2]); Serial.print(' ');
Serial.print(sticks[3]); Serial.print(' ');
Serial.print(rbtn[0]); Serial.print(' ');
Serial.print(rbtn[1]); Serial.print(' ');
Serial.print(rbtn[2]); Serial.print(' ');
Serial.print(rbtn[3]); Serial.print(' ');
Serial.print(rbtn[4]); Serial.print(' ');
Serial.print(rbtn[5]); Serial.print(' ');
Serial.println();
#endif
#endif
// Map to calibration
if (!calibration_mode && !lock_mode) {
sticks[0] = map(sticks[0], calibration.stmn[0], calibration.stmx[0], 0, 1023);
sticks[1] = map(sticks[1], calibration.stmn[1], calibration.stmx[1], 0, 1023);
sticks[2] = map(sticks[2], calibration.stmn[2], calibration.stmx[2], 0, 1023);
sticks[3] = map(sticks[3], calibration.stmn[3], calibration.stmx[3], 0, 1023);
}
// Check buttons states and update timings
for (int i = 0; i < 6; ++i) {
if (buttons.press[i] && !rbtn[i]) { // Button released
if (!buttons.acted[i])
btn_action(i, (millis() - buttons.time[i]) > BTN_LONG_PRESS);
buttons.press[i] = 0;
buttons.time[i] = 0;
} else if (buttons.press[i]) { // Button keeps down
if ((millis() - buttons.time[i]) > BTN_LONG_PRESS && !buttons.acted[i]) { // Toggle long press
btn_action(i, 1);
// buttons.press[i] = 0;
buttons.time[i] = 0;
}
} else if (rbtn[i]) { // Button pressed
buttons.press[i] = 1;
buttons.acted[i] = 0;
buttons.time[i] = millis();
}
}
// Update LED
if (led_state.type == LED_ST_FLASH && (led_state.time + LED_ST_FLASH_TIME) < millis()
||
led_state.type == LED_ST_FAST_FLASH && (led_state.time + LED_ST_FAST_FLASH_TIME) < millis()) { // Flash period done
if (!led_state.state) { // Count cycle as finished, try to begin another one
--led_state.count;
if (led_state.count <= 0) { // Flashing cycles is done
led_state.type = led_state.ptype;
led_set_state(led_state.type == LED_ST_CONST);
} else { // Turn led ON again, begin next flash cycle
led_state.time = millis();
led_set_state(1);
}
} else { // Just turn the led OFF
led_state.time = millis();
led_set_state(0);
}
}
// Update led flashing
if (led_state.type != LED_ST_FLASH && led_state.type != LED_ST_FAST_FLASH) {
if (calibration_mode)
led_set(LED_ST_FAST_FLASH, 4);
else {
// Update led lighting
if (lock_mode)
led_set(LED_ST_CONST, 0);
else
led_set(LED_ST_OFF, 0);
}
}
// If !paired
if (calibration_mode) {
for (int i = 0; i < 4; ++i) {
if (calibration.stmn[i] > sticks[i])
calibration.stmn[i] = sticks[i];
if (calibration.stmx[i] < sticks[i])
calibration.stmx[i] = sticks[i];
}
} else {
// Sending package with sticks
Package pack;
pack.type = PACKAGE_STICKS;
pack.data.sticks.sticks[0] = sticks[0];
pack.data.sticks.sticks[1] = sticks[1];
pack.data.sticks.sticks[2] = sticks[2];
pack.data.sticks.sticks[3] = sticks[3];
bool result = send_package((byte*) &pack, sizeof(Package));
if (!result) {
if (tx_dropped > TX_DROP_EDGE && led_state.type != LED_ST_FLASH && led_state.type != LED_ST_FAST_FLASH)
led_set(LED_ST_FLASH, 4);
#ifdef DEBUG_PRINT
Serial.println("TX failed");
#endif
}
}
}
int send_package(byte* pack, int size) {
if (!radio.write(pack, size)) {
++tx_dropped;
return 0;
} else {
byte payload;
if (radio.isAckPayloadAvailable()) {
radio.read(&payload, sizeof(byte));
tx_dropped = 0;
return 1;
}
++tx_dropped;
return 0;
}
};
void led_set_state(int state) {
if (led_state.state && !state) {
digitalWrite(STLED, 0);
led_state.state = !led_state.state;
} else if (!led_state.state && state) {
analogWrite(STLED, LED_POWER);
led_state.state = !led_state.state;
}
};
void led_set(int type, int count) {
if (type == LED_ST_CONST || type == LED_ST_OFF) {
led_set_state(type == LED_ST_CONST);
led_state.type = type;
} else {
// if was flashing --> rewrite
// if was constant --> move type to ptype & do flashing
if (led_state.type == LED_ST_CONST || led_state.type == LED_ST_OFF)
led_state.ptype = led_state.type;
led_state.type = type;
led_state.count = count;
led_state.time = millis();
led_set_state(1);
}
};
void btn_act(int number) {
buttons.acted[number] = 1;
};
// Override calls for button presses
void btn_action(int number, int lpress) {
#ifdef DEBUG_PRINT
Serial.print("Press for "); Serial.println(number);
#endif
switch(number) {
// calibration
case 0: {
// press = ?
// Lpress = calibration mode
if (lpress) {
if (calibration_mode && !lock_mode) {
// Write calibration values
byte* cal_struct = (byte*) &calibration;
for (int i = 0; i < sizeof(STICK_CALIBRATION); ++i)
EEPROM.write(i, cal_struct[i]);
calibration_mode = 0;
#ifdef DEBUG_PRINT
Serial.println("NEW CALIBRATION: ");
for (int i = 0; i < 4; ++i) {
Serial.print('(');
Serial.print(calibration.stmn[i]);
Serial.print(", ");
Serial.print(calibration.stmx[i]);
Serial.print(") ");
}
Serial.println();
#endif
} else {
for (int i = 0; i < 4; ++i) {
calibration.stmn[i] = 1024;
calibration.stmx[i] = 0;
}
calibration_mode = 1;
}
}
break;
}
case 1: {
// press = ?
// Lpress = lock mode
if (lpress) {
lock_mode = !lock_mode;
}
break;
}
}
led_set(LED_ST_FAST_FLASH, 2);
btn_act(number);
Package pack;
pack.type = PACKAGE_BUTTON;
pack.data.button.number = number;
pack.data.button.lpress = lpress;
bool result = send_package((byte*) &pack, sizeof(Package));
#ifdef DEBUG_PRINT
if (!result)
Serial.println("Button TX failed");
#endif
};
Source for receiver is:
// Flash for self-diy NRF24lo* receiver controller.
// 6 buttons, 4-way sticks.
#include <Servo.h>
#include <SPI.h>
#include "RF24.h"
#define DEBUG_PRINT
#ifdef DEBUG_PRINT
#include <printf.h>
#endif
// IO mappings
#define CONNECT_0 2
#define CONNECT_1 3
#define CONNECT_2 4
#define CONNECT_3 5
#define CONNECT_4 6
#define CONNECT_5 7
#define CONNECT_6 8
#define CONNECT_A0 A0
#define CONNECT_A1 A1
#define CONNECT_A2 A2
#define CONNECT_A3 A3
#define CONNECT_A4 A4
#define CONNECT_A5 A5
// A6, A7 on nano are only analog input
#define CONNECT_A6 A6
#define CONNECT_A7 A7
// Inverters for sticks
#define INVERT_STICK0 0
#define INVERT_STICK1 0
#define INVERT_STICK2 0
#define INVERT_STICK3 0
// Mappings for sticks
#define SERVO_MAP_STICK0 0, 180
#define SERVO_MAP_STICK1 0, 180
#define SERVO_MAP_STICK2 0, 180
#define SERVO_MAP_STICK3 60, 120
#define ANALOG_MAP_STICK0 0, 255
#define ANALOG_MAP_STICK1 0, 255
#define ANALOG_MAP_STICK2 0, 255
#define ANALOG_MAP_STICK3 0, 255
// Optional moddings
// Package types
#define PACKAGE_STICKS 3
#define PACKAGE_BUTTON 5
#define PACKAGE_PING 7
// Used to detect disconnect from the controller
#define CONNECTION_TIMEOUT 100
// Mpdes for output of the motor
// #define MODE_2_DIGITAL_1_ANALOG
#define MODE_2_ANALOG
// Receiver package struct.
// Contains type and values for button or values for sticks
struct Package {
int type;
union {
struct {
int number;
int lpress;
// Used to complete size of the package.
// Without it, payload is not sending for sticks.
int dummy[2];
} button;
struct {
int sticks[4];
} sticks;
} data;
};
// Describes state of a single buttons on controller
// Single press -> 1
// Second press -> 0
struct Button {
bool state;
bool lstate;
};
// Use NRF24lo1 transmitter on pins 7, 8
RF24 radio(9, 10);
byte addresses[][6] = { "TRAAA", "REEEE" };
// Used to detect timed disconnection from the controller
unsigned long last_receive_time;
bool disconnected;
// Servos mapped to sticks
Servo servo[4];
// Buttons states
Button buttons[6];
// Called on connection restored after drop
void on_connection();
// Called on connection dropped
void on_disconnection();
// Called on button state received
void button_action(int button, int lpress);
// Called on sticks state received
void sticks_action(int sticks[4]);
void setPWMNanofrequency(int freq) {
TCCR2B = TCCR2B & 0b11111000 | freq;
TCCR1B = TCCR1B & 0b11111000 | freq;
}
void setup() {
#ifdef DEBUG_PRINT
Serial.begin(115200);
#endif
// Set up receiver
radio.begin();
radio.setChannel(77);
//radio.setAutoAck(1);
//radio.setRetries(0, 8);
radio.enableAckPayload();
radio.setPALevel(RF24_PA_MAX);
//radio.setCRCLength(RF24_CRC_8);
radio.openWritingPipe(addresses[0]);
radio.openReadingPipe(1, addresses[1]);
#ifdef DEBUG_PRINT
// Debugger output
printf_begin();
radio.printDetails();
#endif
radio.startListening();
// Init buttons with 0
buttons[0] = { 0, 0 };
buttons[1] = { 0, 0 };
buttons[2] = { 0, 0 };
buttons[3] = { 0, 0 };
buttons[4] = { 0, 0 };
buttons[5] = { 0, 0 };
// Set up pinout
pinMode(CONNECT_0, OUTPUT);
pinMode(CONNECT_2, OUTPUT);
pinMode(CONNECT_3, OUTPUT);
pinMode(CONNECT_4, OUTPUT);
pinMode(CONNECT_5, OUTPUT);
pinMode(CONNECT_6, OUTPUT);
pinMode(CONNECT_A0, OUTPUT);
pinMode(CONNECT_A1, OUTPUT);
pinMode(CONNECT_A2, OUTPUT);
pinMode(CONNECT_A3, OUTPUT);
pinMode(CONNECT_A4, OUTPUT);
pinMode(CONNECT_A5, OUTPUT);
pinMode(CONNECT_A6, INPUT);
pinMode(CONNECT_A7, INPUT);
// setPWMNanofrequency(0x02);
// Set up servos
servo[0].attach(CONNECT_A4); // Remapped servos to leave three PWM pins
servo[1].attach(CONNECT_A5);
servo[2].attach(CONNECT_5);
servo[3].attach(CONNECT_6);
// Clear disconnect trigger
last_receive_time = millis();
disconnected = 0;
// Reset outputs
digitalWrite(CONNECT_0, LOW);
digitalWrite(CONNECT_2, LOW);
digitalWrite(CONNECT_3, LOW);
digitalWrite(CONNECT_4, LOW);
digitalWrite(CONNECT_5, LOW);
digitalWrite(CONNECT_6, LOW);
digitalWrite(CONNECT_A0, LOW);
digitalWrite(CONNECT_A1, LOW);
digitalWrite(CONNECT_A2, LOW);
digitalWrite(CONNECT_A3, LOW);
digitalWrite(CONNECT_A4, LOW);
digitalWrite(CONNECT_A5, LOW);
// digitalWrite(CONNECT_A6, LOW);
// digitalWrite(CONNECT_A7, LOW);
}
void loop() {
byte payload = 13;
radio.writeAckPayload(1, &payload, sizeof(byte));
if (radio.available()) {
Package pack;
radio.read((byte*) &pack, sizeof(Package));
// Update trigger
last_receive_time = millis();
if (disconnected)
on_connection();
disconnected = 0;
switch(pack.type) {
case PACKAGE_STICKS: {
#ifdef DEBUG_PRINT
Serial.print(pack.data.sticks.sticks[0]); Serial.print(' ');
Serial.print(pack.data.sticks.sticks[1]); Serial.print(' ');
Serial.print(pack.data.sticks.sticks[2]); Serial.print(' ');
Serial.print(pack.data.sticks.sticks[3]); Serial.println();
#endif
if (INVERT_STICK0) pack.data.sticks.sticks[0] = 1024 - pack.data.sticks.sticks[0];
if (INVERT_STICK1) pack.data.sticks.sticks[1] = 1024 - pack.data.sticks.sticks[1];
if (INVERT_STICK2) pack.data.sticks.sticks[2] = 1024 - pack.data.sticks.sticks[2];
if (INVERT_STICK3) pack.data.sticks.sticks[3] = 1024 - pack.data.sticks.sticks[3];
int ssticks[4];
ssticks[0] = map(pack.data.sticks.sticks[0], 0, 1023, SERVO_MAP_STICK0);
ssticks[1] = map(pack.data.sticks.sticks[1], 0, 1023, SERVO_MAP_STICK1);
ssticks[2] = map(pack.data.sticks.sticks[2], 0, 1023, SERVO_MAP_STICK2);
ssticks[3] = map(pack.data.sticks.sticks[3], 0, 1023, SERVO_MAP_STICK3);
int asticks[4];
asticks[0] = map(pack.data.sticks.sticks[0], 0, 1023, ANALOG_MAP_STICK0);
asticks[1] = map(pack.data.sticks.sticks[1], 0, 1023, ANALOG_MAP_STICK1);
asticks[2] = map(pack.data.sticks.sticks[2], 0, 1023, ANALOG_MAP_STICK2);
asticks[3] = map(pack.data.sticks.sticks[3], 0, 1023, ANALOG_MAP_STICK3);
#ifdef DEBUG_PRINT
Serial.print("Servo data: ");
Serial.print(ssticks[0]); Serial.print(' ');
Serial.print(ssticks[1]); Serial.print(' ');
Serial.print(ssticks[2]); Serial.print(' ');
Serial.print(ssticks[3]); Serial.println();
Serial.print("Analog data: ");
Serial.print(asticks[0]); Serial.print(' ');
Serial.print(asticks[1]); Serial.print(' ');
Serial.print(asticks[2]); Serial.print(' ');
Serial.print(asticks[3]); Serial.println();
#endif
sticks_action(pack.data.sticks.sticks, ssticks, asticks);
break;
}
case PACKAGE_BUTTON: {
#ifdef DEBUG_PRINT
Serial.print(pack.data.button.number); Serial.print(' ');
Serial.print(pack.data.button.lpress); Serial.println();
#endif
// Update states of the buttons
if (pack.data.button.lpress)
buttons[pack.data.button.number].lstate = !buttons[pack.data.button.number].lstate;
else
buttons[pack.data.button.number].state = !buttons[pack.data.button.number].state;
button_action(pack.data.button.number, pack.data.button.lpress);
break;
}
}
} else if (!disconnected && millis() - last_receive_time > CONNECTION_TIMEOUT) {
disconnected = 1;
on_disconnection();
}
}
void on_connection() {
};
void on_disconnection() {
// servo[0].write(0);
// servo[1].write(0);
// servo[2].write(0);
// servo[3].write(0);
// analogWrite(CONNECT_A0, 0);
// analogWrite(CONNECT_A1, 0);
// analogWrite(CONNECT_A2, 0);
// analogWrite(CONNECT_A3, 0);
#ifdef MODE_2_DIGITAL_1_ANALOG
digitalWrite(CONNECT_1, LOW);
digitalWrite(CONNECT_2, LOW);
digitalWrite(CONNECT_3, LOW);
#endif
#ifdef MODE_2_ANALOG
digitalWrite(CONNECT_3, LOW);
digitalWrite(CONNECT_4, LOW);
digitalWrite(CONNECT_0, LOW);
#endif
};
void button_action(int button, int lpress) {
switch (button) {
case 0:
case 1:
break;
case 2: {
digitalWrite(CONNECT_A0, buttons[button].state);
break;
}
case 3: {
digitalWrite(CONNECT_A1, buttons[button].state);
break;
}
case 4: {
digitalWrite(CONNECT_A2, buttons[button].state);
break;
}
case 5: {
digitalWrite(CONNECT_A3, buttons[button].state);
break;
}
}
};
void sticks_action(int sticks[4], int ssticks[4], int asticks[4]) {
servo[0].write(ssticks[0]);
servo[1].write(ssticks[1]);
servo[2].write(ssticks[2]);
servo[3].write(ssticks[3]);
// analogWrite(CONNECT_A0, asticks[0]);
// analogWrite(CONNECT_A1, asticks[1]);
// analogWrite(CONNECT_A2, asticks[2]);
// analogWrite(CONNECT_A3, asticks[3]);
// Control H-Bridge over 3, 4 outputs with right stick
int value = (sticks[2] > 500) ? (sticks[2] - 500) : (sticks[2] < 480) ? (480 - sticks[2]) : (0);
if (value < 500)
value = map(value, 0, 480, 0, 255);
else
value = map(value, 0, 1023 - 500, 0, 255);
value = (value > 255) ? 255 : (value < 0) ? 0 : value;
// connecting 2 digital pins as HIGH,LOW / LOW,HIGH and analog as speed value (used in bts79603 bridge)
#ifdef MODE_2_DIGITAL_1_ANALOG
if (sticks[2] > 500) {
digitalWrite(CONNECT_1, HIGH);
digitalWrite(CONNECT_2, LOW);
analogWrite(CONNECT_3, value);
} else if (sticks[2] < 480) {
digitalWrite(CONNECT_1, LOW);
digitalWrite(CONNECT_2, HIGH);
analogWrite(CONNECT_3, value);
} else {
digitalWrite(CONNECT_1, LOW);
digitalWrite(CONNECT_2, LOW);
analogWrite(CONNECT_3, 0);
}
#endif
// connecting 2 analog pins to simple H-Bridge
#ifdef MODE_2_ANALOG
analogWrite(CONNECT_3, sticks[2] > 500 ? value : 0);
analogWrite(CONNECT_4, sticks[2] < 480 ? value : 0);
analogWrite(CONNECT_0, sticks[2] > 500 || sticks[2] < 480);
#endif
};
Transmitter printDetails output:
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x4141415254 0x4545454552
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x4141415254
RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4d
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
Receiver printDetails output:
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0x4545454552 0x4141415254
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0x4545454552
RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x02
RF_CH = 0x4d
RF_SETUP = 0x07
CONFIG = 0x0e
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_MAX
Code used
Following code on receiver caused IO break.
pinMode(CONNECT_A6, INPUT);
pinMode(CONNECT_A7, INPUT);
A6, A7 pins DOES NOT support mode change and this issue made NRF24 connection to fail.
I'm having trouble identifying the cause of a recurrent issue with some arduino code. The code below reads two temperature sensors, sends the result to a PID library, and uses the output to control some relays on a fridge (adding accurate temperature control to a fridge, basically).
The code freezes or the Arduino resets periodically. This happens periodically, but the period changes - it freezes every minimum 30 minutes, maximum about 30 hours.
I suspect that there's an overflow or that I'm writing beyond the range of an array, but I can't find the issue. It's very unlikely that there's a power issue - the arduino is on a 10A 12v supply with a dedicated 5v regulator, so I doubt it.
I'm fairly new to all this and would be very grateful for any pointers or advice - even some tips on how to troubleshoot this unpredictable error would be very appreciated!
Here's the code:
Setup and main loop, also checks an analog input for the set temperature:
// Call libraries for display, sensor, I2C, and memory. Library setup included as well.
#include <avr/pgmspace.h>
char buffer[20];
#include <Time.h>
#include <TimeLib.h>
#include <OneWire.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f,20,4);
#include <DallasTemperature.h>
#include <PID_v1.h>
// Special Characters for the display and display animations
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args) write(args);
#else
#define printByte(args) print(args,BYTE);
#endif
#define ONE_WIRE_BUS 5 //DS18S20 Signal pin on digital 2
uint8_t heart[8] = { 0x0,0xa,0x1f,0x1f,0xe,0x4,0x0};
uint8_t deg[8] = { 0x1c,0x14,0x1c,0x0,0x3,0x4,0x4,0x3};
uint8_t Pv[8] = { 0x1c,0x14,0x1c,0x10,0x10,0x5,0x5,0x2};
uint8_t Sv[8] = { 0xc,0x10,0x8,0x4,0x18,0x5,0x5,0x2};
// end special chars
//************* Begin Variables Setup ***************//
//Sensors (ds18s20 needs additional chatter)
byte addr1[8]= {0x28, 0x3F, 0xB5, 0x3C, 0x05, 0x00, 0x00, 0x25};
byte addr2[8]= {0x28, 0xC7, 0xCD, 0x4C, 0x05, 0x00, 0x00, 0x0D};
byte data1[12];
byte data2[12];
byte MSB = 0;
byte LSB = 0;
float tempRead = 0;
float TemperatureSum = 0;
OneWire ds(ONE_WIRE_BUS);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//controller outputs
int ControlCpin = 6; // control to fridge
int ControlTpin = 8; // control to temperature/heater (get aquarium heater)
int ControlLpin = 7; // control to light
int ControlApin = 9; // control to airflow
//operational vars (the button)
//int buttonPushCounter = 0; // counter for the number of button presses DEPRACATED
int buttonState = 0; // current state of the button
int lastButtonState = 0; // previous state of the button
boolean buttonstate = false; // calculastate of the button (includes timer delay. use this in menus)
int buttontime = 0; // press length measure
int buttontimeon = 0; // necessary for press length measure
//operational vars (sensors and timing)
unsigned int sensorInterval = 20000; // time between readings
unsigned long int sensorTime = 0; // current time
unsigned long int sensorTime2 = 0; // time of last sensor reading
// fans, lights, and timers
unsigned long int fanONmillis = 0;
unsigned long int fanOFFmillis = 0;
byte fanON = 0;
byte fanOFF = 0;
boolean fanstate = false;
unsigned long int Time = 0;
unsigned long int TimeAdjust = 0;
unsigned long int LightON = 0;
unsigned long int LightOFF = 0;
unsigned int Hours = 0;
unsigned int Minutes = 0;
unsigned int Days = 0;
byte daysAdj = 0; //not implemented yet
float tempDiff = 0;
//key var storage
float PvH = 0;
double PvT = 0;
float SvH = 0;
double SvT = 12;
float SvTdisplay = 5.5;
float SvTdisplayOld = 5.5;
float Temp1; //Current readings
float Temp2; //Current readings
float Temp3; //Current readings
// Fridge limits
unsigned int safetyRest = 5; // off this long every hour (minimum) to let the compressor rest in minutes
int minCool = 10; // minimum cooling period in minutes
int coolStart = 0;
byte coolON = 0; // PID attached to this
// Heat limits
byte heatON = 0; // PID attached to this
//cool
double Kp = 0.5;
double Ki = 0.5;
double Kd = 0.5;
double Output;
PID coolPID(&PvT, &Output, &SvT ,Kp,Ki,Kd, REVERSE);
unsigned coolWindowSize = 600; // minutes*10
unsigned long coolWindowStartTime;
unsigned long coolOffElapsed = 0;
long unsigned PIDpos = 0;
unsigned long Outputx = 0;
unsigned long PIDposx = 0;
unsigned long safetyRestx = 0;
// ensure setpoint, input, and outpit are defined
//************* End Variables Setup ***************//
void setup(){
//Sensor start
sensors.begin();
//Pin declarations
pinMode(ControlTpin, OUTPUT); //set outputs
pinMode(ControlLpin, OUTPUT);
pinMode(ControlApin, OUTPUT);
pinMode(ControlCpin, OUTPUT);
digitalWrite(ControlTpin, HIGH); // write outputs HIGH (off in this case) FIRST to prevent startup jitters.
digitalWrite(ControlLpin, HIGH);
digitalWrite(ControlApin, HIGH);
digitalWrite(ControlCpin, HIGH);
//LCD and special chars
Serial.begin(9600);
lcd.begin();
lcd.backlight();
lcd.createChar(0, heart);
lcd.createChar(1, deg);
lcd.createChar(2, Pv);
lcd.createChar(3, Sv);
lcd.clear();
LoadScreen();
HomeSetup();
//PID setup
coolPID.SetOutputLimits(0, coolWindowSize);
coolPID.SetMode(AUTOMATIC);
coolOffElapsed = millis();
}
void loop(){
//if interval has passed, check the sensors, update the triggers, and update the screen
if (millis() - sensorTime2 > sensorInterval){
sensorTime2 = millis();
SensorCheck();
Triggers();
HomeSetup ();
}
SvTdisplay = (float)analogRead(A0);
SvTdisplay = SvTdisplay/40+5;
if(abs(SvTdisplay-SvTdisplayOld) > 0.2){
SvTdisplayOld = SvTdisplay;
lcd.setCursor(2,0);
lcd.print(SvTdisplayOld,1); //svt
lcd.printByte(1);
lcd.print(" ");
SvT = analogRead(A0)/4+50;
}
PIDpos = ((millis()/60000) % (coolWindowSize/10));
}
The following codes a loading screen and updates the screen with current values:
void LoadScreen (){
lcd.clear();
lcd.home();
lcd.setCursor(0,0);
lcd.print(" LaggerLogger ");
lcd.printByte(0);
lcd.setCursor(0,1);
lcd.print(" V2.0 Beepboop!");
delay(3000);
lcd.clear();
}
//write the home screen to the LCD with current data
void HomeSetup(){
lcd.setCursor(0,0);
lcd.printByte(3);
lcd.print(" ");
lcd.print(SvTdisplayOld,1); //svt
lcd.printByte(1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.printByte(2);
lcd.print(" ");
lcd.print(PvT/10,1); //pvt
lcd.printByte(1);
lcd.print(" ");
lcd.setCursor(8,1);
lcd.print(day()-1);
lcd.print("/");
lcd.print(hour());
lcd.print(":");
lcd.print(minute());
lcd.print(" ");
lcd.setCursor(8,0);
lcd.print(Output/10,1);
lcd.print("m/h ");
}
The following checks output values and 'triggers' the relay if its appropriate to do so:
void Triggers () {
coolPID.Compute();
// Check PID
if ((Output/10) > (coolWindowSize/10-PIDpos) && PIDpos > safetyRest ) { //
coolON = 1;
coolStart = millis();
}
else if ((millis() - coolStart) > (minCool * 60000)){
coolON = 0;
}
else {}
// Write to temp relay pins
if (coolON == 1) {
digitalWrite(ControlCpin, LOW);
}
else {
digitalWrite(ControlCpin, HIGH);
}
// Control fans
if (coolON == 1 || heatON == 1 || tempDiff > 1) {
fanOFFmillis = millis();
fanONmillis = millis();
fanstate = true;
digitalWrite(ControlApin, LOW);
}
else {
fanstate = false;
digitalWrite(ControlApin, HIGH);
}
}
The following checks the temperature sensors and does some clock calculations:
void SensorCheck(){
Temp1 = getTemp1();
Temp2 = getTemp2();
//average readings and note the difference
if(Temp1 > 0 && Temp2 >0) {
PvT = (Temp1 + Temp2) / .2;
tempDiff = abs(Temp1 - Temp2);
}
//... unless there's only one thermometer...
else if (Temp1 > 0){
PvT = Temp1*10;
tempDiff = 0;
}
else {
PvT = 999;
tempDiff = 0;
}
//clock update
Time = millis() + TimeAdjust;
Hours = hour();
Minutes = minute();
Days = day();
}
float getTemp1(){
sensors.requestTemperatures();
float z = sensors.getTempCByIndex(0);
return z;
}
float getTemp2(){
sensors.requestTemperatures();
float z = sensors.getTempCByIndex(1);
return z;
}
The problem was that an integer (declared as int coolStart) was later updated to hold the value of millis().
Millis() can be much larger than the 16 bits available to ints - creating an overflow.
Changing the variable declaration to 'unsigned long coolStart = 0;' appears to have solved the problem.
Thanks to everyone for the troubleshooting advice.
I'm using an Arduino Uno with an Adafruit Motor Shield (v2) in order to power and control a motor and a LIS3DH accelerometer. With a simpler code in which the motor just goes forward for a certain number of pulses (output by the encoder), the identical function for the accelerometer outputs correct values. The code is shown below.
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_MotorShield.h>
#include <Adafruit_Sensor.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#define pi 3.14159
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
float distance = 30;
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
unsigned int pulsesperturn = 56 * 64 / 2 ;
float circumference = 5.25 * 3.14159;
int pulses;
//int count = 0;
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif
void setup(void) {
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
AFMS.begin();
Serial.println("LIS3DH test!");
if (! lis.begin(0x19)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
//
}
void loop() {
// // }
// myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
// myMotor->run(FORWARD);
// delay(2500);
// myMotor->setSpeed(0);
// // right = 0;
// delay(1000);
// // right = 1;
// myMotor->run(BACKWARD);
// myMotor->setSpeed(255);
// delay(2500);
// myMotor->setSpeed(0);
// // right = 0;
// delay(1000);
// // right = 1;
myMotor->run(FORWARD);
myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
if (pulsesperturn <= pulses ) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
myMotor->setSpeed(0);
stoppedAccel();
pulses = 0;
}
// Then print out the raw data
// Serial.print("X: "); Serial.print(lis.x);
// Serial.print(" \tY: "); Serial.print(lis.y);
// Serial.print(" \tZ: "); Serial.print(lis.z);
// for (int a = 1; a < 20; a = a + 1) {
// lis.read(); // get X Y and Z data at once
// sensors_event_t event;
// lis.getEvent(&event);
//
// /* Display the results (acceleration is measured in m/s^2) */
// // Serial.print(" \tAngle: "); Serial.print(angle);
// //
// // Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// // Serial.println(" m/s^2 ");
//
// Serial.println();
// //
// // char buffer[5];
// // Serial.print("#S|WRITEDATA|[");
// // Serial.print(angle); // accels
// // Serial.println("]#");
//
// // WriteAccel();
// delay(10);
// }
// myMotor->run(FORWARD);
//
// myMotor->run(RELEASE);
// myMotor->setSpeed(255);
// if (distance / circumference * pulsesperturn <= pulses) {
// myMotor->setSpeed(0);
// delay(2500);
// }
// myMotor->setSpeed(255);
// myMotor->run(FORWARD);
// pulses = 0;
Serial.print("pulses = ");
Serial.println(pulses);
attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
/* Or....get a new sensor event, normalized */
}
void counter()
{
pulses++;
}
void stoppedAccel()
{
for (int a = 1; a < 150; a = a + 1) {
lis.read(); // get X Y and Z data at once
sensors_event_t event;
lis.getEvent(&event);
float angle = asin(event.acceleration.z / 9.81) * 180 / pi ;
Serial.print(" \tAngle: "); Serial.print(angle);
//
// Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// Serial.println(" m/s^2 ");
Serial.println();
//
// char buffer[5];
// Serial.print("#S|WRITEDATA|[");
// Serial.print(angle); // accels
// Serial.println("]#");
delay(10);
}
}
In this code, which runs the motor forward for a distance 6 times and then runs it backward for the same distance it went forward, the motor runs correctly and the accelerometer says that it has been found but it outputs exclusively null values.
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//The sample code for driving one way motor encoder
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
//byte encoder0PinALast;
int duration;//the number of the pulses
//unsigned long timeold;
unsigned int pulsesperturn = 56 * 64 / 2;
float widthDetector = 10; //distance needed, in cm
float circumference = 5.25 * 3.14159;
float pulses;
int count = 0;
#define pi 3.14159
//bool answered = 0;
//float distanceTotal = 100;
//float waitTime = 0.01;
//unsigned int pulsesper100forward = 56 * 64 ;
//unsigned int pulsesper100back = 56 * 64 ;
int b = 0;
float conversion = 171 / 169;
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif
void setup(void)
{
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
AFMS.begin();
Serial.println("LIS3DH test!");
if (! lis.begin(0x19)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
// myMotor->run(FORWARD);
myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
}
void loop() {
motorDirection();
}
void counter()
{
pulses++;
}
void bcounter()
{
b++;
}
void motorDirection()
{
while (b < 6) {
myMotor->run(FORWARD);
readInt();
if (500 * conversion <= pulses) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
pulses = 0;
bcounter();
if (b == 6) {
stoppedAccel();
}
delay(1500);
}
// break;
}
while (b == 6) {
myMotor->run(BACKWARD);
readInt();
if (500 * b <= pulses) {
myMotor->run(RELEASE);
myMotor->run(RELEASE);
bcounter();
stoppedAccel();
pulses = 0;
delay(500);
break;
}
}
while (b > 6) {
b = 0;
break;
}
}
// 169 forward per 1000, 171 backward
void stoppedAccel()
{
for (int a = 1; a < 150; a = a + 1) {
lis.read(); // get X Y and Z data at once
sensors_event_t event;
lis.getEvent(&event);
float angle = asin(event.acceleration.z / 9.81) * 180 / pi ;
Serial.print(" \tAngle: "); Serial.print(angle);
//
// Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// Serial.println(" m/s^2 ");
Serial.println();
//
// char buffer[5];
// Serial.print("#S|WRITEDATA|[");
// Serial.print(angle); // accels
// Serial.println("]#");
delay(100);
}
}
void readInt()
{
attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
Serial.print("pulses = ");
Serial.println(pulses);
}
I have tried various things but I have little background in CS, especially in C++, so my attempts haven't been fruitful. Any advice would be helpful.
The issue was using delay(). How exactly the hardware works, I'm not sure, but I believe blocking it in such a way threw off the hardware so that it was outputting null. Below is the corrected code using millis().
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//The sample code for driving one way motor encoder
const byte encoder0pinA = 2;//A pin -> the interrupt pin 0
//byte encoder0PinALast;
int duration;//the number of the pulses
//unsigned long timeold;
unsigned int pulsesperturn = 56 * 64 / 2;
float widthDetector = 10; //distance needed, in cm
float circumference = 5.25 * 3.14159;
float pulses;
int count = 0;
#define pi 3.14159
float angle;
const long interval = 1000;
unsigned long previousMillis;
//bool answered = 0;
//float distanceTotal = 100;
//float waitTime = 0.01;
//unsigned int pulsesper100forward = 56 * 64 ;
//unsigned int pulsesper100back = 56 * 64 ;
int b = 0;
float conversion = 171 / 169;
#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
#define Serial SerialUSB
#endif
void setup(void)
{
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
AFMS.begin();
Serial.println("LIS3DH test!");
if (! lis.begin(0x19)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1);
}
Serial.println("LIS3DH found!");
lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
// myMotor->run(FORWARD);
myMotor->setSpeed(255); // this will end up changing but is constant for testing validation purposes
}
void loop() {
motorDirection();
// stoppedAccel();
}
void counter()
{
pulses++;
}
void bcounter()
{
b++;
}
void motorDirection()
{
//serial.write
while (b < 6) {
myMotor->run(FORWARD);
readInt();
if (500 * conversion <= pulses) {
myMotor->run(RELEASE);
bcounter();
previousMillis = millis();
timing();
// previousMillis = currentMillis;
pulses = 0;
if (b == 6) {
stoppedAccel();
}
}
break;
}
while (b == 6) {
myMotor->run(BACKWARD);
readInt();
if (500 * b <= pulses) {
myMotor->run(RELEASE);
pulses = 0;
bcounter();
stoppedAccel();
break;
}
}
while (b > 6) {
b = 0;
break;
}
}
// 169 forward per 1000, 171 backward
void stoppedAccel()
{
for (int a = 1; a < 200; a = a + 1) {
lis.read(); // get X Y and Z data at once
sensors_event_t event;
lis.getEvent(&event);
angle = asin(event.acceleration.z / 9.81) * 180 / pi ;
Serial.print(" \tAngle: "); Serial.print(angle);
//
// Serial.print("\t\tX: "); Serial.print(event.acceleration.x);
// Serial.print(" \tY: "); Serial.print(event.acceleration.y);
// Serial.print(" \tZ: "); Serial.print(event.acceleration.z);
// Serial.println(" m/s^2 ");
Serial.println();
//
// char buffer[5];
// Serial.print("#S|WRITEDATA|[");
// Serial.print(angle); // accels
// Serial.println("]#");
delay(10);
}
}
void readInt()
{
attachInterrupt(digitalPinToInterrupt(encoder0pinA), counter, RISING);
Serial.print("pulses = ");
Serial.println(pulses);
}
void timing()
{
while (millis() - previousMillis <= interval) {
myMotor->run(RELEASE);
}
}
I am working on a robotic arm that has six servos which is being controlled by an arduino uno. The servos are analog servos from adafruit and they are special in the sense that you can get feedback from the servos, i.e their actual position after you told it where to go. What I am working on is trying to adapt this example code to include six servos instead of one. https://github.com/adafruit/Feedback-Servo-Record-and-Play/blob/master/servo_recordplay.ino
Here is my code so far and its errors
// Example code for recording and playing back servo motion with a
// analog feedback servo
// http://www.adafruit.com/products/1404
#include <Servo.h>
#include <EEPROM.h>
#define CALIB_MAX 512
#define CALIB_MIN 100
#define SAMPLE_DELAY 25 // in ms, 50ms seems good
uint8_t recordButtonPin = 12;
uint8_t playButtonPin = 7;
uint8_t servo1Pin = 9;
uint8_t servo2Pin = 10;
uint8_t servo1FeedbackPin = A0;
uint8_t servo2FeedbackPin = A1;
uint8_t servo3FeedbackPin = A2;
uint8_t servo4FeedbackPin = A3;
uint8_t servo5FeedbackPin = A4;
uint8_t servo6FeedbackPin = A5;
uint8_t ledPin = 13;
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
void setup() {
Serial.begin(9600);
pinMode(recordButtonPin, INPUT);
digitalWrite(recordButtonPin, HIGH);
pinMode(playButtonPin, INPUT);
digitalWrite(playButtonPin, HIGH);
pinMode(ledPin, OUTPUT);
Serial.println("Servo RecordPlay");
}
void loop() {
if (! digitalRead(recordButtonPin)) {
delay(10);
// wait for released
while (! digitalRead(recordButtonPin));
delay(20);
// OK released!
recordAllServos(servo1Pin, servo1FeedbackPin, recordButtonPin);
}
if (! digitalRead(playButtonPin)) {
delay(10);
// wait for released
while (! digitalRead(playButtonPin));
delay(20);
// OK released!
playAllServo(servo1Pin, playButtonPin);
}
}
void playAllServo(uint8_t servoPin, uint8_t buttonPin) {
uint16_t addr = 0;
Serial.println("Playing");
servo1.attach(servo1Pin);
while (digitalRead(buttonPin)) {
uint8_t x = EEPROM.read(addr);
Serial.print("Read EE: "); Serial.print(x);
if (x == 255) break;
// map to 0-180 degrees
x = map(x, 0, 254, 0, 180);
Serial.print(" -> "); Serial.println(x);
servo1.write(x);
delay(SAMPLE_DELAY);
addr++;
if (addr == 512) break;
}
Serial.println("Done");
servo1.detach();
delay(250);
}
void recordAllServos(uint8_t servoPin, uint8_t buttonPin) {
uint16_t addr = 0;
Serial.println("Recording");
digitalWrite(ledPin, HIGH);
pinMode(servo1FeedbackPin, INPUT);
pinMode(servo2FeedbackPin, INPUT);
pinMode(servo3FeedbackPin, INPUT);
pinMode(servo4FeedbackPin, INPUT);
pinMode(servo5FeedbackPin, INPUT);
pinMode(servo6FeedbackPin, INPUT);
while (digitalRead(buttonPin))
{
readServo(servo1FeedbackPin);
readServo(servo2FeedbackPin);
readServo(servo3FeedbackPin);
readServo(servo4FeedbackPin);
readServo(servo5FeedbackPin);
readServo(servo6FeedbackPin);
if (addr > 506) break;
delay(SAMPLE_DELAY);
}
if (addr != 1024) EEPROM.write(addr, 255);
digitalWrite(ledPin, LOW);
Serial.println("Done");
delay(250);
}
void readAllServo(uint8_t analogPin)
{
uint16_t a = analogRead(analogPin);
Serial.print("Read analog pin "); Serial.print(analogPin); Serial.print(": ");
Serial.print(a);
if (a < CALIB_MIN) a = CALIB_MIN;
if (a > CALIB_MAX) a = CALIB_MAX;
a = map(a, CALIB_MIN, CALIB_MAX, 0, 254);
Serial.print(" -> "); Serial.println(a);
EEPROM.write(addr, a);
addr++;
}
The errors that I am getting from the arduino ide are
Teachable_Arm_Mark.cpp: In function 'void loop()':
Teachable_Arm_Mark:10: error: too many arguments to function 'void recordAllServos(uint8_t, uint8_t)'
Teachable_Arm_Mark:49: error: at this point in file
Teachable_Arm_Mark.cpp: In function 'void recordAllServos(uint8_t, uint8_t)':
Teachable_Arm_Mark:100: error: 'readServo' was not declared in this scope
Teachable_Arm_Mark.cpp: In function 'void readAllServo(uint8_t)':
Teachable_Arm_Mark:127: error: 'addr' was not declared in this scope
Any help much appreciated
Thanks
In void loop you have
recordAllServos(servo1Pin, servo1FeedbackPin, recordButtonPin);
but recordAllServos is declared as
void recordAllServos(uint8_t servoPin, uint8_t buttonPin)
Hence too many arguments 3 vs 2...