Skip to content

Commit

Permalink
now runs on a rpi pico
Browse files Browse the repository at this point in the history
joshua-8 committed Jun 19, 2024
1 parent 98f3258 commit 89b7ab7
Showing 3 changed files with 82 additions and 41 deletions.
5 changes: 5 additions & 0 deletions clear_eeprom/clear_eeprom.ino
Original file line number Diff line number Diff line change
@@ -2,9 +2,14 @@
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
EEPROM.begin(1024);
for (int i = 0 ; i < EEPROM.length() ; i++) {
EEPROM.write(i, 255);
delay(1);
}
#if defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
EEPROM.commit(); // rp2040 EEPROM library requires this to be used to write the updated data to the flash that is simulating EEPROM (flash has more limited cycles)
#endif
digitalWrite(LED_BUILTIN, LOW);
}
void loop() {
73 changes: 54 additions & 19 deletions gbg_program/_Save_Recall.ino
Original file line number Diff line number Diff line change
@@ -5,31 +5,45 @@
If the checksum reveals data corruption, the car enters a safe mode instead of driving with wrong values.
*/

const unsigned int repeat_space = 200; // space between each copy of a variable
const unsigned int repeat_space = 200; // space between each copy of a variable (larger than number of bytes needed for settings)


byte bufP = 0;
char buf[60] = { 0 }; // buffer to fill with Serial input

char resultBuf[15] = { 0 }; // for replying with the received value

uint32_t eepromCRC = 0;

boolean errorCorrectionPerformed = false;

void settingsMemory()
{
byte settingsMemoryKeyRead; // the read value
unsigned int settingsMemoryKeyReadAddress = 0;

errorCorrectionPerformed = false;
EEPROMread(settingsMemoryKeyReadAddress, settingsMemoryKeyRead);
#if defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
if (errorCorrectionPerformed) {
EEPROM.commit(); // rp2040 EEPROM library requires this to be used to write the updated data to the flash that is simulating EEPROM (flash has more limited cycles)
}
#endif

if (settingsMemoryKeyRead != settings_memory_key) { // eeprom doesn't have the key value, use default instead of not yet programmed EEPROM
settingsMemoryKeyReadAddress = 0;
EEPROMwrite(settingsMemoryKeyReadAddress, settings_memory_key);
#if defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
EEPROM.commit(); // rp2040 EEPROM library requires this to be used to write the updated data to the flash that is simulating EEPROM (flash has more limited cycles)
#endif
saveSettings();
movementAllowed = false;
}
} // end of special case of overwriting using default values
recallSettings();
}

byte bufP = 0;
char buf[60] = { 0 }; // buffer to fill with Serial input

char resultBuf[15] = { 0 }; // for replying with the received value

uint32_t eepromCRC = 0;

void settingsSerial() {
char in = Serial.read();
int8_t in = Serial.read();
if (in != -1) {
if (in == ',') {
buf[bufP] = 0; // null terminator
@@ -274,6 +288,9 @@ void settingsSerial() {
} else if (strcmp(k, "REVERT") == 0) {
unsigned int settingsMemoryKeyAddr = 0;
EEPROMwrite(settingsMemoryKeyAddr, settings_memory_key + 1); // so that on reset the arduino discards EEPROM
#if defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
EEPROM.commit();
#endif
delay(5000); // trigger wdt
} else if (strcmp(k, "REBOOT") == 0) {
delay(5000); // trigger wdt
@@ -368,12 +385,15 @@ void saveSettings()
EEPROMwrite(addressW, STEERING_OFF_SWITCH_PIN);

EEPROMwrite(addressW, eepromCRC);
#if defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
EEPROM.commit();
#endif
}
void recallSettings()
{
unsigned int addressR = 1;
eepromCRC = 0;

errorCorrectionPerformed = false;
EEPROMread(addressR, CONTROL_RIGHT);
EEPROMread(addressR, CONTROL_CENTER_X);
EEPROMread(addressR, CONTROL_LEFT);
@@ -426,6 +446,13 @@ void recallSettings()
uint32_t tempEepromCRC = eepromCRC;
uint32_t readCRC = 0;
EEPROMread(addressR, readCRC);

#if defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
if (errorCorrectionPerformed) {
EEPROM.commit(); // rp2040 EEPROM library requires this to be used to write the updated data to the flash that is simulating EEPROM (flash has more limited cycles)
}
#endif

// a checksum isn't a perfect guarantee that the stored data is valid, but likely better than 1 in 1000
if (tempEepromCRC != readCRC) { // calculated checksum of data doesn't match stored checksum of data
delay(50);
@@ -439,7 +466,6 @@ void recallSettings()
// stop sending any signals out of the pins (set all to inputs, even if it's on a Mega)
for (byte pin = 2; pin <= 100; pin++) {
pinMode(pin, INPUT);
digitalWrite(pin, LOW);
}
pinMode(LED_BUILTIN, OUTPUT);
delay(50);
@@ -512,9 +538,9 @@ void EEPROMwrite(unsigned int& address, const T & value)
// modified from code by Nick Gammon https://forum.arduino.cc/t/how-do-i-convert-a-struct-to-a-byte-array-and-back-to-a-struct-again/261791/8
const byte* p = (const byte*)&value;
for (unsigned int i = 0; i < sizeof value; i++) {
EEPROM.update(address, *p); // Three copies of the data are stored in EEPROM to detect and correct single bit errors
EEPROM.update(address + repeat_space, *p);
EEPROM.update(address + repeat_space * 2, *p);
EEPROM.write(address, *p); // Three copies of the data are stored in EEPROM to detect and correct single bit errors
EEPROM.write(address + repeat_space, *p);
EEPROM.write(address + repeat_space * 2, *p);
tempEepromCRC = crc_update(tempEepromCRC, *p);
// writes 3 copies
address++;
@@ -538,14 +564,23 @@ void EEPROMread(unsigned int& address, T & value)
} else { // disagreement, correct the corrupted bit
//(if two bits flip, both in the same place, then instead of correcting the error, the error is kept, but this is hopefully unlikely and likely to be caught by the checksum)
*p = (a & b) | (b & c) | (c & a); // bitwise majority https://stackoverflow.com/a/29892322
EEPROM.update(address, *p); // replace all three copies with the majority value
EEPROM.update(address + repeat_space, *p);
EEPROM.update(address + repeat_space * 2, *p);
EEPROM.write(address, *p); // replace all three copies with the majority value
EEPROM.write(address + repeat_space, *p);
EEPROM.write(address + repeat_space * 2, *p);

errorCorrectionPerformed = true;
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
delay(50);
// correcting errors can take a while. don't let the watchdog timeout
#ifdef AVR
wdt_reset();
#elif defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
rp2040.wdt_reset();
#endif

}
eepromCRC = crc_update(eepromCRC, *p);
address++;
45 changes: 23 additions & 22 deletions gbg_program/gbg_program.ino
Original file line number Diff line number Diff line change
@@ -20,15 +20,15 @@
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///// joystick input reader constants /////
int CONTROL_RIGHT = 42; // use to calibrate joystick (value from the X axis of the joystick when all the way to the left)
int CONTROL_CENTER_X = 492; // use to calibrate joystick (value from the X axis of the joystick when it is centered)
int CONTROL_LEFT = 950; // use to calibrate joystick (value from the X axis of the joystick when all the way to the right)
int X_DEADZONE = 50; // radius around center where joystick is considered centered
int16_t CONTROL_RIGHT = 42; // use to calibrate joystick (value from the X axis of the joystick when all the way to the left)
int16_t CONTROL_CENTER_X = 492; // use to calibrate joystick (value from the X axis of the joystick when it is centered)
int16_t CONTROL_LEFT = 950; // use to calibrate joystick (value from the X axis of the joystick when all the way to the right)
int16_t X_DEADZONE = 50; // radius around center where joystick is considered centered

int CONTROL_UP = 927; // use to calibrate joystick (value from the Y axis of the joystick when all the way to the bottom)
int CONTROL_CENTER_Y = 495; // use to calibrate joystick (value from the Y axis of the joystick when it is centered)
int CONTROL_DOWN = 43; // use to calibrate joystick (value from the Y axis of the joystick when all the way to the top)
int Y_DEADZONE = 50; // radius around center where joystick is considered centered
int16_t CONTROL_UP = 927; // use to calibrate joystick (value from the Y axis of the joystick when all the way to the bottom)
int16_t CONTROL_CENTER_Y = 495; // use to calibrate joystick (value from the Y axis of the joystick when it is centered)
int16_t CONTROL_DOWN = 43; // use to calibrate joystick (value from the Y axis of the joystick when all the way to the top)
int16_t Y_DEADZONE = 50; // radius around center where joystick is considered centered

///// input processor constants /////
float ACCELERATION_FORWARD = 0.25; //change # to change the amount of acceleration when going forward (1/#=seconds to reach max speed)
@@ -50,23 +50,23 @@ boolean SCALE_ACCEL_WITH_SPEED = true; //set true if using a speed knob and you
boolean REVERSE_TURN_IN_REVERSE = false; //flip turn axis when backing up so that the car goes in the direction the joystick is pointed when in reverse

// calibrate signals to motor controllers
int LEFT_MOTOR_CENTER = 1500;
int LEFT_MOTOR_SLOW = 50; // CENTER +- what? makes the motor start to turn
int LEFT_MOTOR_FAST = 500; // CENTER +- what? makes the motor go at full speed (if you want to limit the max speed, use FASTEST_FORWARD AND FASTEST_BACKWARD)
int LEFT_MOTOR_PULSE = 90; // CENTER +- (sign of _SLOW) what? makes the car move a bit for the pulse on start
int RIGHT_MOTOR_CENTER = 1500;
int RIGHT_MOTOR_SLOW = 50; // CENTER +- what? makes the motor start to turn
int RIGHT_MOTOR_FAST = 500; // CENTER +- what? makes the motor go at full speed (if you want to limit the max speed, use FASTEST_FORWARD AND FASTEST_BACKWARD)
int RIGHT_MOTOR_PULSE = 90; // CENTER +- (sign of _SLOW) what? makes the car move a bit for the pulse on start
int START_MOTOR_PULSE_TIME = 150; // milliseconds for pulse on start
int16_t LEFT_MOTOR_CENTER = 1500;
int16_t LEFT_MOTOR_SLOW = 50; // CENTER +- what? makes the motor start to turn
int16_t LEFT_MOTOR_FAST = 500; // CENTER +- what? makes the motor go at full speed (if you want to limit the max speed, use FASTEST_FORWARD AND FASTEST_BACKWARD)
int16_t LEFT_MOTOR_PULSE = 90; // CENTER +- (sign of _SLOW) what? makes the car move a bit for the pulse on start
int16_t RIGHT_MOTOR_CENTER = 1500;
int16_t RIGHT_MOTOR_SLOW = 50; // CENTER +- what? makes the motor start to turn
int16_t RIGHT_MOTOR_FAST = 500; // CENTER +- what? makes the motor go at full speed (if you want to limit the max speed, use FASTEST_FORWARD AND FASTEST_BACKWARD)
int16_t RIGHT_MOTOR_PULSE = 90; // CENTER +- (sign of _SLOW) what? makes the car move a bit for the pulse on start
int16_t START_MOTOR_PULSE_TIME = 150; // milliseconds for pulse on start

boolean ENABLE_STARTUP_PULSE = true; // small movement to indicate that the car is ready

int JOY_CALIB_COUNT = 800; // how long does joystick need to be centered? (units of somewhere between 1 and 2 milliseconds)
int16_t JOY_CALIB_COUNT = 800; // how long does joystick need to be centered? (units of somewhere between 1 and 2 milliseconds)

boolean USE_SPEED_KNOB = false; // true = use speed knob, false = don't read the speed knob (see FASTEST_FORWARD, FASTEST_BACKWARD and TURN_SPEED to limit speed)
int SPEED_KNOB_SLOW_VAL = 1060; // can be slightly out of range, so that it just gets really slow instead of stopping
int SPEED_KNOB_FAST_VAL = 0; //analogRead value when knob is turned fully towards "fast" setting
int16_t SPEED_KNOB_SLOW_VAL = 1060; // can be slightly out of range, so that it just gets really slow instead of stopping
int16_t SPEED_KNOB_FAST_VAL = 0; //analogRead value when knob is turned fully towards "fast" setting


//////////////////////////////////////////// PINS /////////////////////////////////////
@@ -187,9 +187,10 @@ void setup() {
sei();
#elif defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
rp2040.wdt_begin(2000);
rp2040.wdt_reset();
EEPROM.begin(1024);
#endif

//initialize variables
joyXVal = 512;
joyYVal = 512;
@@ -255,7 +256,7 @@ void loop()
#ifdef AVR
wdt_reset();
#elif defined(ARDUINO_ARCH_MBED_RP2040)|| defined(ARDUINO_ARCH_RP2040)
rp2040.wdt_reset();
rp2040.wdt_reset();
#endif

if (use_memory)

0 comments on commit 89b7ab7

Please sign in to comment.