Not sure how to best describe what is happening and ask how to fix it but here it goes.
The application is having having two hiking poles instrumented with load cells to measure the force through the poles. When I apply a load to both load cells (relatively equally) they seem to follow the same pattern up until a certain threshold where one of the load cells seems to not be able to measure any higher of a load. This should not be the case because they are rated for much higher than the load that I am applying in this instance. I have attached a graph of what I mean for reference. I have tried to change my code to read one load cell at a time and I still get the same results.
Any ideas?
#include <RTClib.h>
#include <SD.h>
#include <Wire.h>
#include <Button.h>
RTC_DS1307 RTC; // define the Real Time Clock object
#define ADDRESS_1 (0x48) //device i2c address
# define CONFIG_REG (0x01)
#define CONV_REG (0x00)
//config reg
//OS
#define OS (0x8000)
//mux
#define MUX_0_1 (0x0000)
#define MUX_0_3 (0x1000)
#define MUX_1_3 (0x2000)
#define MUX_2_3 (0x3000)
#define MUX_0_GND (0x4000)
#define MUX_1_GND (0x5000)
#define MUX_2_GND (0x6000)
#define MUX_3_GND (0x7000)
//pga
#define PGA_2_3RD (0x0000)
#define PGA_1 (0x0200)
#define PGA_2 (0x0400)
#define PGA_4 (0x0600)
#define PGA_8 (0x0800)
#define PGA_16 (0x0A00)
#define PGA_16_1 (0x0C00) //TBR
#define PGA_16_2 (0x0E00) //TBR
//mode
#define SINGLE_SHOT (0x0100)
#define CONT (0x0000)
//samples per second
#define DRD_8 (0X0000)
#define DRD_16 (0X0020)
#define DRD_32 (0X0040)
#define DRD_64 (0X0060)
#define DRD_128 (0X0080)
#define DRD_250 (0X00A0)
#define DRD_475 (0X00C0)
#define DRD_860 (0X00E0)
//SET UP YOUR ADC HERE
//#define SETUP (OS|PGA_16|SINGLE_SHOT|DRD_860)// see line 93!!!
#define SETUP (OS|PGA_16|SINGLE_SHOT|DRD_860)// see line 93!!!
float cL;
float cR;
Button button = Button(8,PULLDOWN);
#define greenLED 3
#define redLED 4
long previousMillis = 0;
long interval = 9; // interval in milliseconds (10ms => 100Hz)
#define ECHO_TO_SERIAL 0 // echo data to serial port (set to 0 to turn off which should increase speed)
#define WAIT_TO_START 0 // Wait for serial input in setup()
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str)
{
Serial.print("error: ");
Serial.println(str);
// red LED indicates error
digitalWrite(redLED, HIGH);
while (1);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup(){
Serial.begin(115200);
Wire.begin();
writeRegister(OS | ADDRESS_1, CONFIG_REG, SETUP | MUX_0_1);
writeRegister(OS | ADDRESS_1, CONFIG_REG, SETUP | MUX_2_3);
//c = conversionFactor(SETUP); //* 4096. ;// / 32768.;
cL = conversionFactor(SETUP)*1.91732;
cR = conversionFactor(SETUP)*2.02114;
// use debugging LEDs
pinMode(redLED, OUTPUT);
pinMode(greenLED, OUTPUT);
#if WAIT_TO_START
Serial.println("Type any character to start");
while (!Serial.available());
#endif //WAIT_TO_START
// initialize the SD card
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
error("Card failed, or not present");
}
Serial.println("card initialized.");
// create a new file
char filename[] = "HIKING00.CSV";
for (uint8_t i = 1; i < 100; i++) {
filename[6] = i / 10 + '0';
filename[7] = i % 10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
// logfile = SD.open(filename, FILE_WRITE);
logfile = SD.open(filename, (O_READ | O_WRITE | O_CREAT));
break; // leave the loop!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
// connect to RTC
// Wire.begin();
if (!RTC.begin()) {
logfile.println("RTC failed");
#if ECHO_TO_SERIAL
Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
}
logfile.println("millis,leftpoleforce,rightpoleforce");
#if ECHO_TO_SERIAL
Serial.println("millis,leftpoleforce,rightpoleforce");
#endif //ECHO_TO_SERIAL
}
byte pressCount = 0;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop(){
if (button.uniquePress())
pressCount++;
switch(pressCount){
case 1:{
digitalWrite(greenLED, HIGH);
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
previousMillis = currentMillis;
// log milliseconds since starting
uint32_t m = millis();
logfile.print(m); // milliseconds since start
logfile.print(", ");
#if ECHO_TO_SERIAL
Serial.print(m); // milliseconds since start
Serial.print(", ");
#endif
// readChannel(ADDRESS_1, MUX_0_1)*c;
// readChannel(ADDRESS_1, MUX_2_3)*c;
logfile.print(readChannel(ADDRESS_1, MUX_0_1)*cL-1.564);
logfile.print(", ");
logfile.print(readChannel(ADDRESS_1, MUX_2_3)*cR+1.998);
logfile.println();
#if ECHO_TO_SERIAL
Serial.print(readChannel(ADDRESS_1, MUX_0_1)*cL);
Serial.print(", ");
Serial.print(readChannel(ADDRESS_1, MUX_2_3)*cR);
Serial.println();
#endif //ECHO_TO_SERIAL
digitalWrite(greenLED, LOW);
} }
break;
case 2:{
logfile.flush();
logfile.close();
digitalWrite(greenLED, LOW);
digitalWrite(redLED, HIGH);
delay(250);
digitalWrite(redLED, LOW);
delay(250);
digitalWrite(redLED, HIGH);
delay(250);
digitalWrite(redLED, LOW);
delay(250);
digitalWrite(redLED, HIGH);
delay(250);
digitalWrite(redLED, LOW);
delay(250);
digitalWrite(redLED, HIGH);
delay(250);
digitalWrite(redLED, LOW);
delay(250);
digitalWrite(redLED, HIGH);
delay(250);
digitalWrite(redLED, LOW);
pressCount = 0;
}
break;
}
}
void writeRegister(uint8_t i2cAddress, uint8_t reg, uint16_t value) { //static
Wire.beginTransmission(i2cAddress);
Wire.write((uint8_t)reg);
Wire.write((uint8_t)(value >> 8));
Wire.write((uint8_t)(value & 0xFF));
Wire.endTransmission();
}
uint16_t readRegister(uint8_t i2cAddress, uint8_t reg) { //static
Wire.beginTransmission(i2cAddress);
Wire.write(reg);
Wire.endTransmission();
Wire.requestFrom(i2cAddress, 2);
return ((Wire.read() << 8) | Wire.read());
}
boolean conversionReady(uint8_t i2cAddress) {
uint16_t r = readRegister(ADDRESS_1, CONFIG_REG);
return (r & (1 << 15)) >> 15;
}
int readChannel(uint8_t i2cAddress, uint16_t channel) {
writeRegister(i2cAddress, CONFIG_REG, SETUP | channel);
while (!conversionReady(i2cAddress));//only for Single shot
uint16_t r = readRegister(ADDRESS_1, CONV_REG);
return r;
}
float conversionFactor(uint16_t confReg) {
float PGA = (confReg & 0x0E00) >> 9 ;
if (PGA == 0) {
PGA = .75;
} else {
PGA = pow(2., ((confReg & 0x0E00) >> 9) - 1);
}
return 1. / PGA;
}