I wrote a sketch which reads a scale using sparkfun's 7802 and their library, moves a motor using the accelstepper.h library, and reading an encoder via a DB9 connector. I wanted to increase the speed at which I was reading everything so I ordered a portenta to try and do this in parallel.
I cannot run my orginal program because the sparkfun 7802 library uses #include< EEprom.h> and the portenta does not have an EEprom.
Where should I go from here?
#include <AccelStepper.h>
#include <MultiStepper.h>
// Integrates ScaleWeight, MotorSetPVA, Temp
#include <Wire.h>
//#include <EEPROM.h> //Needed to record user settings
#include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_NAU8702
#include <SparkFunTMP102.h>
//Encoder Stuff
const int pinA = 2, DRO_B = 3, phaseLookup[] = {0,-1,1,-1,1,0,-1,-1,-1,1,0,1,1,1,-1,0};
volatile bool A = false, B = false, updated = false;
volatile int counter = 0, phase = 0;
//Temp Sensor
TMP102 sensor0;
//Scale
NAU7802 myScale; // Create instance of the NAU7802 class
// EEPROM locations to store 4-byte variables
#define LOCATION_CALIBRATION_FACTOR 0 // Float, requires 4 bytes of EEPROM
#define LOCATION_ZERO_OFFSET 10 // Must be more than 4 away from previous spot. Long, requires 4 bytes of EEPROM
bool settingsDetected = false; // Used to prompt user to calibrate their scale
// Create an array to take average of weights. This helps smooth out jitter.
#define AVG_SIZE 4
float avgWeights[AVG_SIZE];
byte avgWeightSpot = 0;
//Stepper stuff
#define STEPPER_DIR_PIN 9
#define STEPPER_STEP_PIN 8
int Position;
int Velocity;
int Acceleration;
// Define stepper and the pins the will use
AccelStepper stepper(AccelStepper::DRIVER, STEPPER_STEP_PIN, STEPPER_DIR_PIN);
void setup()
{
Serial.begin(115200);
Serial.println("Motor and Scale and Temp and Encoder");
Wire.begin();
Wire.setClock(400000); // Qwiic Scale is capable of running at 400kHz if desired
//Encoder pinMode(pinA, INPUT);
pinMode(DRO_B, INPUT);
attachInterrupt(digitalPinToInterrupt(pinA), trig, CHANGE);
attachInterrupt(digitalPinToInterrupt(DRO_B), trig, CHANGE);
//Temp Sensor init
if(!sensor0.begin())
{
Serial.println("Cannot connect to TMP102.");
Serial.println("Is the board connected? Is the device ID correct?");
while(1);
}
Serial.println("Connected to TMP102!");
// set the number of consecutive faults before triggering alarm.
// 0-3: 0:1 fault, 1:2 faults, 2:4 faults, 3:6 faults.
sensor0.setFault(0); // Trigger alarm immediately
// set the polarity of the Alarm. (0:Active LOW, 1:Active HIGH).
sensor0.setAlertPolarity(1); // Active HIGH
// set the sensor in Comparator Mode (0) or Interrupt Mode (1).
sensor0.setAlertMode(0); // Comparator Mode.
// set the Conversion Rate (how quickly the sensor gets a new reading)
//0-3: 0:0.25Hz, 1:1Hz, 2:4Hz, 3:8Hz
sensor0.setConversionRate(2);
//set Extended Mode.
//0:12-bit Temperature(-55C to +128C) 1:13-bit Temperature(-55C to +150C)
sensor0.setExtendedMode(0);
//set T_HIGH, the upper limit to trigger the alert on
sensor0.setHighTempF(85.0); // set T_HIGH in F
//sensor0.setHighTempC(29.4); // set T_HIGH in C
//set T_LOW, the lower limit to shut turn off the alert
sensor0.setLowTempF(84.0); // set T_LOW in F
//sensor0.setLowTempC(26.67); // set T_LOW in C
//Scale init
if (myScale.begin() == false)
{
Serial.println("Scale not detected. Please check wiring. Freezing...");
while (1)
;
}
Serial.println("Scale detected!");
readSystemSettings(); // Load zeroOffset and calibrationFactor from EEPROM
myScale.setSampleRate(NAU7802_SPS_320); // Increase to max sample rate
myScale.calibrateAFE(); // Re-cal analog front end when we change gain, sample rate, or channel
Serial.print("Zero offset: ");
Serial.println(myScale.getZeroOffset());
Serial.print("Calibration factor: ");
Serial.println(myScale.getCalibrationFactor());
// Stepper initialize
stepper.setMaxSpeed(2500.0);
stepper.setAcceleration(4000.0);
}
void loop()
{
//Temp Stuff
float temperature;
boolean alertPinState, alertRegisterState;
sensor0.wakeup();
// Stepper Stuff
readSerialInput();
stepper.run();
//Loop Print
loopPrint();
}
void loopPrint(){
//DRO
Serial.print("DRO position: ");
Serial.print(String(counter));
//Weight
float currentWeight = myScale.getWeight();
Serial.print(" Weight: ");
Serial.print(currentWeight, 2); // Print 2 decimal places
//Temp
Serial.print(" Temperature: ");
float temperature = sensor0.readTempF();
Serial.println(temperature);
delay(250);
}
// Sets Stepper position, Velocity, and acceleration
void readSerialInput()
{
if (Serial.available() > 0)
{
// read the incoming string:
String incomingString = Serial.readStringUntil('$'); // read the incoming byte:
String Command = incomingString.substring(0, 3);
if (Command == "DRO")
{
Serial.print("DRO position: ");
Serial.println(String(counter));
}
// If command starts with POS, set Position
if (Command == "POS")
{
Position = incomingString.substring(3).toInt();
Serial.print("Position set to: ");
Serial.println(Position);
stepper.moveTo(Position);
}
if (Command == "VEL")
{
Velocity = incomingString.substring(3).toInt();
Serial.print("Velocity set to: ");
Serial.println(Velocity);
stepper.setMaxSpeed(Velocity);
}
if (Command == "ACC")
{
Acceleration = incomingString.substring(3).toInt();
Serial.print("Acceleration set to: ");
Serial.println(Acceleration);
stepper.setAcceleration(Acceleration);
}
if (Command == "TMP")
{
Serial.print("Temperature: ");
float temperature = sensor0.readTempF();
Serial.print(temperature);
}
if (Command == "WEI")
{
if (myScale.available() == true)
{
float currentWeight = myScale.getWeight();
Serial.print("Weight: ");
Serial.println(currentWeight, 2); // Print 2 decimal places
if (settingsDetected == false)
{
Serial.print("\tScale not calibrated. Press 'c'.");
}
}
}
if (Command == "TAR")
{
myScale.calculateZeroOffset();
}
if (Command == "CAL")
{
calibrateScale();
}
}
}
//Encoder Function
void trig()
{
A = digitalRead(pinA);
B = digitalRead(DRO_B);
phase <<= 1;
phase |= A;
phase <<= 1;
phase |= B;
phase &= 0xF;
counter += phaseLookup[phase];
//updated = true;
}
// Gives user the ability to set a known weight on the scale and calculate a calibration factor
void calibrateScale(void)
{
Serial.println();
Serial.println();
Serial.println(F("Scale calibration"));
Serial.println(F("Setup scale with no weight on it. Press a key when ready."));
while (Serial.available())
Serial.read(); // Clear anything in RX buffer
while (Serial.available() == 0)
delay(10); // Wait for user to press key
myScale.calculateZeroOffset(64); // Zero or Tare the scale. Average over 64 readings.
Serial.print(F("New zero offset: "));
Serial.println(myScale.getZeroOffset());
Serial.println(F("Place known weight on scale. Press a key when weight is in place and stable."));
while (Serial.available())
Serial.read(); // Clear anything in RX buffer
while (Serial.available() == 0)
delay(10); // Wait for user to press key
Serial.print(F("Please enter the weight, without units, currently sitting on the scale (for example '4.25'): "));
while (Serial.available())
Serial.read(); // Clear anything in RX buffer
while (Serial.available() == 0)
delay(10); // Wait for user to press key
// Read user input
float weightOnScale = Serial.parseFloat();
Serial.println();
myScale.calculateCalibrationFactor(weightOnScale, 64); // Tell the library how much weight is currently on it
Serial.print(F("New cal factor: "));
Serial.println(myScale.getCalibrationFactor(), 2);
Serial.print(F("New Scale Reading: "));
Serial.println(myScale.getWeight(), 2);
recordSystemSettings(); // Commit these values to EEPROM
}
// Record the current system settings to EEPROM
void recordSystemSettings(void)
{
// Get various values from the library and commit them to NVM
EEPROM.put(LOCATION_CALIBRATION_FACTOR, myScale.getCalibrationFactor());
EEPROM.put(LOCATION_ZERO_OFFSET, myScale.getZeroOffset());
}
// Reads the current system settings from EEPROM
// If anything looks weird, reset setting to default value
void readSystemSettings(void)
{
float settingCalibrationFactor; // Value used to convert the load cell reading to lbs or kg
long settingZeroOffset; // Zero value that is found when scale is tared
// Look up the calibration factor
EEPROM.get(LOCATION_CALIBRATION_FACTOR, settingCalibrationFactor);
if (settingCalibrationFactor == 0xFFFFFFFF)
{
settingCalibrationFactor = 0; // Default to 0
EEPROM.put(LOCATION_CALIBRATION_FACTOR, settingCalibrationFactor);
}
// Look up the zero tare point
EEPROM.get(LOCATION_ZERO_OFFSET, settingZeroOffset);
if (settingZeroOffset == 0xFFFFFFFF)
{
settingZeroOffset = 1000L; // Default to 1000 so we don't get inf
EEPROM.put(LOCATION_ZERO_OFFSET, settingZeroOffset);
}
// Pass these values to the library
myScale.setCalibrationFactor(settingCalibrationFactor);
myScale.setZeroOffset(settingZeroOffset);
settingsDetected = true; // Assume for the moment that there are good cal values
if (settingCalibrationFactor < 0.1 || settingZeroOffset == 1000)
settingsDetected = false; // Defaults detected. Prompt user to cal scale.
}
1 post - 1 participant