Compare commits
6 Commits
0755bcfe40
...
master
Author | SHA1 | Date | |
---|---|---|---|
e29aac17ca | |||
ba96c67893 | |||
451cefdae0 | |||
aba9954053 | |||
cc123773b5 | |||
1833ecf607 |
152
firmware/main/XGZP.cpp
Normal file
152
firmware/main/XGZP.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
Copyright 2019 stickbreaker@github
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "XGZP.h"
|
||||
#include <Wire.h>
|
||||
|
||||
#define I2C_ERROR_OK 0
|
||||
|
||||
XGZP::XGZP(void):
|
||||
_devID(0)
|
||||
{}
|
||||
|
||||
bool XGZP::begin(uint8_t devID) {
|
||||
_devID=0;
|
||||
Wire.begin();
|
||||
Wire.beginTransmission(devID);
|
||||
Wire.write(0xA5); // Sys Config Register
|
||||
Wire.endTransmission();
|
||||
uint8_t count = Wire.requestFrom(devID, (uint8_t) 1);
|
||||
if (count == 1) {
|
||||
uint8_t reg = Wire.read();
|
||||
Serial.printf(" Read System Configuration register = 0x%02X\n", reg);
|
||||
|
||||
Wire.beginTransmission(devID);
|
||||
Wire.write(0xA5); // sys configuration register
|
||||
// DAC ON, Single Conversion, Vout=Fixed by Vext*1.5, Vext=3.6V, Calibrated Output, Diag=on
|
||||
Wire.write(0xFD); //
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if(err != 0){
|
||||
Serial.printf("Writing to register 0xA5 value 0xFD failed = %d\n", err);
|
||||
return false; // fail
|
||||
}
|
||||
|
||||
bool ready = false;
|
||||
uint32_t tick = millis(); // timout
|
||||
while (!ready && (millis() - tick < 1000)) {
|
||||
Wire.beginTransmission(devID);
|
||||
ready = I2C_ERROR_OK == Wire.endTransmission();
|
||||
}
|
||||
if (ready) {
|
||||
Wire.beginTransmission(devID);
|
||||
Wire.write(0xA5);
|
||||
Wire.write(0x0A);
|
||||
err = Wire.endTransmission();
|
||||
if(err != 0){
|
||||
Serial.printf("Writing to register 0xA5 value 0x0A failed = %d\n", err);
|
||||
return false; // fail
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.println("Timeout, Sensor did not respond after first config set.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.println("Reading from 0xA5 failed");
|
||||
return false;
|
||||
}
|
||||
_devID = devID;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XGZP::read(float * reading) {
|
||||
if ((! _devID ) || ( *reading == NULL )) {
|
||||
Serial.println("Not initialized or no return value location, returning");
|
||||
if (*reading != NULL) *reading = NAN;
|
||||
return false;
|
||||
}
|
||||
|
||||
float XGZPC_Value = 0;
|
||||
bool ready = false;
|
||||
uint32_t tick = millis();
|
||||
while (!ready && (millis() - tick < 1000)) { // Wait upto 1sec for conversion to complete
|
||||
Wire.beginTransmission(_devID);
|
||||
Wire.write(0x02); // status register
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err == I2C_ERROR_OK) {
|
||||
uint8_t count = Wire.requestFrom(_devID, (uint8_t) 1); // get status byte
|
||||
if (count==1) { // got data
|
||||
uint8_t status = Wire.read();
|
||||
ready = (status & 0x01) == 0x01; // data ready!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
Wire.beginTransmission(_devID);
|
||||
Wire.write(0x06); // data register
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err == I2C_ERROR_OK) {
|
||||
uint8_t count = Wire.requestFrom(_devID, (uint8_t) 3); // get data
|
||||
if (count == 3) { // got data
|
||||
XGZPC_Value = Wire.read() * 65536.0 + Wire.read() * 256.0 + Wire.read();
|
||||
XGZPC_Value = XGZPC_Value / 8.0;
|
||||
//Serial.print("Pa Value: ");
|
||||
//Serial.println(XGZPC_Value);
|
||||
|
||||
XGZPC_Value = XGZPC_Value / 6895.0;
|
||||
|
||||
*reading = XGZPC_Value;
|
||||
Wire.beginTransmission(_devID); // start next sample?
|
||||
Wire.write(0x30);
|
||||
Wire.write(0x0a); // Data and Temp conversion, Single shot, immediate
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err != 0) {
|
||||
Serial.printf(" next Sample start failed? i2cError = %d\n", err);
|
||||
return true; // data valid, next sample will be a problem.
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Serial.println("Read data failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.println("setData address failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Wire.beginTransmission(_devID); // start next sample?
|
||||
Wire.write(0x30);
|
||||
Wire.write(0x0a); // Data and Temp conversion, Single shot, immediate
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err != 0) {
|
||||
Serial.printf(" Next Sample start failed? i2cError = %d\n", err);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
39
firmware/main/XGZP.h
Normal file
39
firmware/main/XGZP.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2019 stickbreaker@github
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XGZP_h
|
||||
#define XGZP_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class XGZP {
|
||||
|
||||
public:
|
||||
XGZP();
|
||||
|
||||
bool begin( uint8_t devID = 0x6D );
|
||||
bool read( float * reading);
|
||||
private:
|
||||
uint8_t _devID;
|
||||
|
||||
};
|
||||
#endif
|
@@ -2,23 +2,36 @@
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "hardware.h"
|
||||
#include "XGZP.h"
|
||||
|
||||
bool simulating = false;
|
||||
float simulatedPressure = 0.0;
|
||||
float inflatePSIPerSecond = 0.0;
|
||||
float deflatePSIPerSecond = 0.0;
|
||||
float pressureChangeRate = 0.0;
|
||||
float deflateOffsetMultiplier = 0.0;
|
||||
float inflateOffsetMultiplier = 0.0;
|
||||
float offsetMultiplier = 0.0;
|
||||
bool simulating = true;
|
||||
double simulatedPressure = 0.0;
|
||||
double inflatePSIPerSecond = 0.0;
|
||||
double deflatePSIPerSecond = 0.0;
|
||||
double pressureChangeRate = 0.0;
|
||||
double deflateOffsetMultiplier = 0.0;
|
||||
double inflateOffsetMultiplier = 0.0;
|
||||
double offsetMultiplier = 0.0;
|
||||
float value = 1;
|
||||
|
||||
XGZP sensor;
|
||||
|
||||
void initHardware() {
|
||||
Serial.println("Initializing hardware...");
|
||||
|
||||
if(!sensor.begin()){
|
||||
Serial.printf("Error initializing Sensor\n Locking up.");
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
void initSimulation() {
|
||||
simulating = true;
|
||||
simulatedPressure = (float) random(10, 30);
|
||||
simulatedPressure = (double) random(10, 30);
|
||||
inflatePSIPerSecond = 0.0303;
|
||||
deflatePSIPerSecond = 0.0958;
|
||||
deflateOffsetMultiplier = random(3, 10) / 100.0;
|
||||
inflateOffsetMultiplier = 1.0 - deflateOffsetMultiplier;
|
||||
inflateOffsetMultiplier = random(103, 160) / 100.0;
|
||||
offsetMultiplier = 1.0;
|
||||
}
|
||||
|
||||
@@ -26,36 +39,33 @@ void tickSimulation() {
|
||||
static unsigned long lastTick = millis();
|
||||
|
||||
if (millis() > lastTick + 100) {
|
||||
float pressureDelta = (millis() - lastTick) / 1000.0 * pressureChangeRate;
|
||||
double pressureDelta = (millis() - lastTick) / 1000.0 * pressureChangeRate;
|
||||
|
||||
simulatedPressure += pressureDelta;
|
||||
lastTick = millis();
|
||||
|
||||
Serial.print("Simulated pressure: ");
|
||||
Serial.println(simulatedPressure);
|
||||
}
|
||||
}
|
||||
|
||||
void measurePressure(float &pressureValue, int pin) {
|
||||
void measurePressure(double &pressureValue) {
|
||||
if (simulating) {
|
||||
float adjusted = simulatedPressure + (random(-100, 100) / 100.0);
|
||||
double adjusted = simulatedPressure + (random(-100, 100) / 100.0);
|
||||
adjusted *= offsetMultiplier;
|
||||
pressureValue = 0.99 * pressureValue + 0.01 * adjusted;
|
||||
} else {
|
||||
int sensorValue = analogRead(pin);
|
||||
float adjusted = 0.098 * sensorValue - 16.56 + 3.58;
|
||||
sensor.read(&value);
|
||||
double adjusted = 1.368 * value - 6.4;
|
||||
pressureValue = 0.99 * pressureValue + 0.01 * adjusted;
|
||||
}
|
||||
}
|
||||
|
||||
void resamplePressure(float &pressureValue, int pin) {
|
||||
void resamplePressure(double &pressureValue) {
|
||||
if (simulating) {
|
||||
float adjusted = simulatedPressure + (random(-100, 100) / 100.0);
|
||||
double adjusted = simulatedPressure + (random(-100, 100) / 100.0);
|
||||
adjusted *= offsetMultiplier;
|
||||
pressureValue = adjusted;
|
||||
} else {
|
||||
int sensorValue = analogRead(pin);
|
||||
float adjusted = 0.098 * sensorValue - 16.56 + 3.58;
|
||||
sensor.read(&value);
|
||||
double adjusted = 1.368 * value - 6.4;
|
||||
pressureValue = adjusted;
|
||||
}
|
||||
}
|
||||
@@ -64,11 +74,20 @@ void setSoleniod(int solenoidState) {
|
||||
if (solenoidState == SOLENOID_STOP) {
|
||||
pressureChangeRate = 0.0;
|
||||
offsetMultiplier = 1.0;
|
||||
|
||||
digitalWrite(RELAY1_PIN, HIGH);
|
||||
digitalWrite(RELAY2_PIN, HIGH);
|
||||
} else if (solenoidState == SOLENOID_INFLATE) {
|
||||
pressureChangeRate = inflatePSIPerSecond;
|
||||
offsetMultiplier = inflateOffsetMultiplier;
|
||||
|
||||
digitalWrite(RELAY1_PIN, LOW);
|
||||
digitalWrite(RELAY2_PIN, HIGH);
|
||||
} else if (solenoidState == SOLENOID_DEFLATE) {
|
||||
pressureChangeRate = -deflatePSIPerSecond;
|
||||
offsetMultiplier = deflatePSIPerSecond;
|
||||
|
||||
digitalWrite(RELAY1_PIN, HIGH);
|
||||
digitalWrite(RELAY2_PIN, LOW);
|
||||
}
|
||||
}
|
||||
|
@@ -7,10 +7,18 @@
|
||||
#define SOLENOID_INFLATE 1
|
||||
#define SOLENOID_DEFLATE 2
|
||||
|
||||
#define RELAY1_PIN 11
|
||||
#define RELAY2_PIN 7
|
||||
|
||||
#define PRESSURE_SENSOR_PIN A0
|
||||
|
||||
extern double simulatedPressure;
|
||||
|
||||
void initSimulation();
|
||||
void initHardware();
|
||||
void tickSimulation();
|
||||
void measurePressure(float &pressureValue, int pin);
|
||||
void resamplePressure(float &pressureValue, int pin);
|
||||
void measurePressure(double &pressureValue);
|
||||
void resamplePressure(double &pressureValue);
|
||||
void setSoleniod(int solenoidState);
|
||||
|
||||
#endif
|
||||
|
@@ -1,7 +1,16 @@
|
||||
// Tire Inflation Firmware
|
||||
//
|
||||
// Board: Adafruit Feather nRF52832
|
||||
// Setup: https://learn.adafruit.com/bluefruit-nrf52-feather-learning-guide/arduino-bsp-setup
|
||||
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <Adafruit_FeatherOLED.h>
|
||||
#include <Adafruit_FeatherOLED.h> // make sure to add:
|
||||
// #define VBATPIN 0
|
||||
// #define VBAT_MULTIPLIER 0
|
||||
// to Adafruit_FeatherOLED.cpp
|
||||
// or Adafruit_FeatherOLED_SH110X.cpp
|
||||
|
||||
#include "hardware.h"
|
||||
|
||||
@@ -16,16 +25,14 @@
|
||||
#define ENTER_BUTTON 30
|
||||
#define DOWN_BUTTON 27
|
||||
|
||||
#define PRESSURE_SENSOR_PIN A0
|
||||
|
||||
Adafruit_FeatherOLED oled = Adafruit_FeatherOLED();
|
||||
|
||||
static const unsigned char PROGMEM arrow[] =
|
||||
{ B10000000,
|
||||
B11000000,
|
||||
B11100000,
|
||||
B11000000,
|
||||
B10000000};
|
||||
//static const unsigned char PROGMEM arrow[] =
|
||||
//{ B10000000,
|
||||
// B11000000,
|
||||
// B11100000,
|
||||
// B11000000,
|
||||
// B10000000};
|
||||
//oled.drawBitmap(0, 1, arrow, 8, 5, 1);
|
||||
|
||||
|
||||
@@ -38,7 +45,7 @@ enum buttonStates {
|
||||
NUM_BUTTONSTATES
|
||||
};
|
||||
|
||||
enum screenStates {
|
||||
enum machineStates {
|
||||
BOOT_UP,
|
||||
PRESSURE,
|
||||
SET_POINT,
|
||||
@@ -51,16 +58,37 @@ enum screenStates {
|
||||
SAY_HOLD,
|
||||
SAY_TIMEOUT,
|
||||
SETTINGS,
|
||||
NUM_SCREENSTATES
|
||||
};
|
||||
|
||||
static const char* stateLabels[] = {
|
||||
"BOOT_UP",
|
||||
"PRESSURE",
|
||||
"SET_POINT",
|
||||
"INIT_RUN",
|
||||
"BEGIN_RUN",
|
||||
"MEASURING",
|
||||
"RUNNING",
|
||||
"SAY_DONE",
|
||||
"SAY_CANCEL",
|
||||
"SAY_HOLD",
|
||||
"SAY_TIMEOUT",
|
||||
"SETTINGS",
|
||||
};
|
||||
|
||||
|
||||
enum buttonStates upButton = OPEN;
|
||||
enum buttonStates enterButton = OPEN;
|
||||
enum buttonStates downButton = OPEN;
|
||||
|
||||
float pressureValue = 0.0;
|
||||
enum machineStates machineState = BOOT_UP;
|
||||
double pressureValue = 0.0;
|
||||
int pressureSetPoint = 0;
|
||||
double initialPressure = 0.0;
|
||||
//double runningPressure = 0.0;
|
||||
double sampledPressure = 0.0;
|
||||
double runningRateInv = 0.0;
|
||||
|
||||
int debounceValue(float value) {
|
||||
int debounceValue(double value) {
|
||||
static int prevValue = (int) value;
|
||||
|
||||
if (abs(prevValue - value) > 0.4) {
|
||||
@@ -82,34 +110,64 @@ void setup()
|
||||
pinMode(ENTER_BUTTON, INPUT); // Has external pullup
|
||||
pinMode(DOWN_BUTTON, INPUT_PULLUP);
|
||||
|
||||
pinMode(RELAY1_PIN, OUTPUT);
|
||||
pinMode(RELAY2_PIN, OUTPUT);
|
||||
digitalWrite(RELAY1_PIN, HIGH);
|
||||
digitalWrite(RELAY2_PIN, HIGH);
|
||||
|
||||
#ifdef SIMULATE
|
||||
initSimulation();
|
||||
#else
|
||||
initHardware();
|
||||
#endif
|
||||
|
||||
resamplePressure(pressureValue, PRESSURE_SENSOR_PIN);
|
||||
resamplePressure(pressureValue);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
measurePressure(pressureValue, PRESSURE_SENSOR_PIN);
|
||||
measurePressure(pressureValue);
|
||||
pollButtons();
|
||||
runUI();
|
||||
runStateMachine();
|
||||
logData();
|
||||
|
||||
#ifdef SIMULATE
|
||||
tickSimulation();
|
||||
#endif
|
||||
}
|
||||
|
||||
void runUI() {
|
||||
static enum screenStates screenState = BOOT_UP;
|
||||
static enum screenStates nextState = BOOT_UP;
|
||||
void logData() {
|
||||
static unsigned long lastLogTime = millis();
|
||||
|
||||
if (millis() > lastLogTime + 100) {
|
||||
//Serial.print("millis: ");
|
||||
//Serial.print(millis());
|
||||
Serial.print(", pressure: ");
|
||||
Serial.print(pressureValue);
|
||||
#ifdef SIMULATE
|
||||
Serial.print(", simulated: ");
|
||||
Serial.print(simulatedPressure);
|
||||
#endif
|
||||
Serial.print(", sampled: ");
|
||||
Serial.print(sampledPressure);
|
||||
//Serial.print(", rate (inv): ");
|
||||
//Serial.print(runningRateInv);
|
||||
Serial.print(", setpoint: ");
|
||||
Serial.print(pressureSetPoint);
|
||||
Serial.print(", state: ");
|
||||
Serial.print(stateLabels[machineState]);
|
||||
Serial.println("");
|
||||
|
||||
lastLogTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void runStateMachine() {
|
||||
static enum machineStates nextState = BOOT_UP;
|
||||
|
||||
static unsigned long timer = millis();
|
||||
|
||||
static int pressureSetPoint = 0;
|
||||
static unsigned long startTime = millis();
|
||||
//static float initialPressure = 0.0;
|
||||
//static float runningPressure = 0.0;
|
||||
static float sampledPressure = 0.0;
|
||||
static unsigned long stopTime = millis();
|
||||
static bool isInflating = false;
|
||||
static bool isDeflating = false;
|
||||
|
||||
@@ -118,18 +176,10 @@ void runUI() {
|
||||
|
||||
oled.clearDisplay();
|
||||
|
||||
Serial.print("pressure: ");
|
||||
Serial.print(pressureValue);
|
||||
Serial.print(", sampled: ");
|
||||
Serial.print(sampledPressure);
|
||||
Serial.print(", setpoint: ");
|
||||
Serial.print(pressureSetPoint);
|
||||
Serial.println("");
|
||||
|
||||
switch (screenState) {
|
||||
switch (machineState) {
|
||||
case BOOT_UP:
|
||||
if (millis() >= timer + 2000) {
|
||||
screenState = PRESSURE;
|
||||
machineState = PRESSURE;
|
||||
}
|
||||
|
||||
oled.setCursor(0,0);
|
||||
@@ -145,25 +195,25 @@ void runUI() {
|
||||
|
||||
case PRESSURE:
|
||||
if (enterButton == PRESSED) {
|
||||
screenState = SAY_HOLD;
|
||||
machineState = SAY_HOLD;
|
||||
nextState = PRESSURE;
|
||||
timer = millis();
|
||||
} else if (enterButton == HELD) {
|
||||
; // settings?
|
||||
} else if (upButton == PRESSED) {
|
||||
screenState = SET_POINT;
|
||||
machineState = SET_POINT;
|
||||
pressureSetPoint = debouncedPressureValue+1;
|
||||
timer = millis();
|
||||
} else if (downButton == PRESSED) {
|
||||
screenState = SET_POINT;
|
||||
machineState = SET_POINT;
|
||||
pressureSetPoint = debouncedPressureValue-1;
|
||||
timer = millis();
|
||||
} else if (upButton == HELD) {
|
||||
screenState = SET_POINT;
|
||||
machineState = SET_POINT;
|
||||
pressureSetPoint = debouncedPressureValue+1;
|
||||
timer = millis();
|
||||
} else if (downButton == HELD) {
|
||||
screenState = SET_POINT;
|
||||
machineState = SET_POINT;
|
||||
pressureSetPoint = debouncedPressureValue-1;
|
||||
timer = millis();
|
||||
}
|
||||
@@ -178,12 +228,12 @@ void runUI() {
|
||||
|
||||
case SET_POINT:
|
||||
if (enterButton == PRESSED) {
|
||||
screenState = SAY_HOLD;
|
||||
machineState = SAY_HOLD;
|
||||
nextState = SET_POINT;
|
||||
timer = millis();
|
||||
} else if (enterButton == HELD) {
|
||||
timer = millis();
|
||||
screenState = INIT_RUN;
|
||||
machineState = INIT_RUN;
|
||||
} else if (upButton == PRESSED) {
|
||||
timer = millis();
|
||||
pressureSetPoint++;
|
||||
@@ -199,7 +249,7 @@ void runUI() {
|
||||
pressureSetPoint--;
|
||||
delay(75);
|
||||
} else if (millis() >= timer + TIMEOUT_TIME) {
|
||||
screenState = SAY_TIMEOUT;
|
||||
machineState = SAY_TIMEOUT;
|
||||
nextState = PRESSURE;
|
||||
timer = millis();
|
||||
}
|
||||
@@ -216,10 +266,10 @@ void runUI() {
|
||||
break;
|
||||
|
||||
case INIT_RUN:
|
||||
//initialPressure = pressureValue;
|
||||
initialPressure = pressureValue;
|
||||
startTime = millis();
|
||||
timer = millis();
|
||||
screenState = BEGIN_RUN;
|
||||
machineState = BEGIN_RUN;
|
||||
|
||||
oled.setCursor(0,0);
|
||||
oled.setTextSize(1);
|
||||
@@ -237,7 +287,7 @@ void runUI() {
|
||||
isInflating = false;
|
||||
} else {
|
||||
setSoleniod(SOLENOID_STOP);
|
||||
screenState = SAY_DONE;
|
||||
machineState = SAY_DONE;
|
||||
nextState = PRESSURE;
|
||||
}
|
||||
|
||||
@@ -249,32 +299,51 @@ void runUI() {
|
||||
if (millis() >= timer + 5000) {
|
||||
//runningPressure = pressureValue;
|
||||
setSoleniod(SOLENOID_STOP);
|
||||
screenState = MEASURING;
|
||||
machineState = MEASURING;
|
||||
timer = millis();
|
||||
stopTime = millis();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MEASURING:
|
||||
if (millis() < timer + 500) {
|
||||
// wait for solenoids to settle before averaging
|
||||
resamplePressure(pressureValue);
|
||||
|
||||
}
|
||||
|
||||
if (millis() >= timer + 3000) {
|
||||
sampledPressure = pressureValue;
|
||||
|
||||
runningRateInv = (stopTime - startTime) / (sampledPressure - initialPressure);
|
||||
|
||||
//Serial.print("stopTime: ");
|
||||
//Serial.print(stopTime);
|
||||
//Serial.print(", startTime: ");
|
||||
//Serial.print(startTime);
|
||||
//Serial.print(", sampledPressure: ");
|
||||
//Serial.print(sampledPressure);
|
||||
//Serial.print(", initialPressure: ");
|
||||
//Serial.print(initialPressure);
|
||||
//Serial.print(", rate: ");
|
||||
//Serial.print(runningRateInv);
|
||||
//Serial.println("");
|
||||
|
||||
initialPressure = sampledPressure;
|
||||
|
||||
if (isInflating && (int) sampledPressure >= pressureSetPoint) {
|
||||
screenState = SAY_DONE;
|
||||
machineState = SAY_DONE;
|
||||
nextState = PRESSURE;
|
||||
} else if (isDeflating && (int) sampledPressure <= pressureSetPoint) {
|
||||
screenState = SAY_DONE;
|
||||
machineState = SAY_DONE;
|
||||
nextState = PRESSURE;
|
||||
} else {
|
||||
screenState = RUNNING;
|
||||
machineState = RUNNING;
|
||||
}
|
||||
|
||||
timer = millis();
|
||||
}
|
||||
|
||||
if (millis() < timer + 500) {
|
||||
// wait for solenoids to settle before averaging
|
||||
resamplePressure(pressureValue, PRESSURE_SENSOR_PIN);
|
||||
startTime = millis();
|
||||
}
|
||||
|
||||
setSoleniod(SOLENOID_STOP);
|
||||
@@ -290,25 +359,30 @@ void runUI() {
|
||||
|
||||
case RUNNING:
|
||||
if (enterButton == PRESSED) {
|
||||
screenState = SAY_CANCEL;
|
||||
setSoleniod(SOLENOID_STOP);
|
||||
machineState = SAY_CANCEL;
|
||||
nextState = PRESSURE;
|
||||
timer = millis();
|
||||
} else if (upButton == PRESSED) {
|
||||
screenState = SAY_CANCEL;
|
||||
setSoleniod(SOLENOID_STOP);
|
||||
machineState = SAY_CANCEL;
|
||||
nextState = PRESSURE;
|
||||
timer = millis();
|
||||
} else if (downButton == PRESSED) {
|
||||
screenState = SAY_CANCEL;
|
||||
setSoleniod(SOLENOID_STOP);
|
||||
machineState = SAY_CANCEL;
|
||||
nextState = PRESSURE;
|
||||
timer = millis();
|
||||
}
|
||||
|
||||
if (isInflating && millis() >= timer + 20000) {
|
||||
screenState = MEASURING;
|
||||
machineState = MEASURING;
|
||||
timer = millis();
|
||||
stopTime = millis();
|
||||
} else if (isDeflating && millis() >= timer + 10000) {
|
||||
screenState = MEASURING;
|
||||
machineState = MEASURING;
|
||||
timer = millis();
|
||||
stopTime = millis();
|
||||
}
|
||||
|
||||
if (isInflating) {
|
||||
@@ -341,7 +415,7 @@ void runUI() {
|
||||
|
||||
case SAY_DONE:
|
||||
if (millis() >= timer + 3000) {
|
||||
screenState = nextState;
|
||||
machineState = nextState;
|
||||
timer = millis();
|
||||
}
|
||||
|
||||
@@ -355,7 +429,7 @@ void runUI() {
|
||||
|
||||
case SAY_CANCEL:
|
||||
if (millis() >= timer + 1000) {
|
||||
screenState = nextState;
|
||||
machineState = nextState;
|
||||
timer = millis();
|
||||
}
|
||||
|
||||
@@ -369,7 +443,7 @@ void runUI() {
|
||||
|
||||
case SAY_HOLD:
|
||||
if (millis() >= timer + 500) {
|
||||
screenState = nextState;
|
||||
machineState = nextState;
|
||||
timer = millis();
|
||||
}
|
||||
|
||||
@@ -383,7 +457,7 @@ void runUI() {
|
||||
|
||||
case SAY_TIMEOUT:
|
||||
if (millis() >= timer + 1000) {
|
||||
screenState = nextState;
|
||||
machineState = nextState;
|
||||
timer = millis();
|
||||
}
|
||||
|
||||
|
152
firmware/pressure_digital/XGZP.cpp
Normal file
152
firmware/pressure_digital/XGZP.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
Copyright 2019 stickbreaker@github
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "XGZP.h"
|
||||
#include <Wire.h>
|
||||
|
||||
#define I2C_ERROR_OK 0
|
||||
|
||||
XGZP::XGZP(void):
|
||||
_devID(0)
|
||||
{}
|
||||
|
||||
bool XGZP::begin(uint8_t devID) {
|
||||
_devID=0;
|
||||
Wire.begin();
|
||||
Wire.beginTransmission(devID);
|
||||
Wire.write(0xA5); // Sys Config Register
|
||||
Wire.endTransmission();
|
||||
uint8_t count = Wire.requestFrom(devID, (uint8_t) 1);
|
||||
if (count == 1) {
|
||||
uint8_t reg = Wire.read();
|
||||
Serial.printf(" Read System Configuration register = 0x%02X\n", reg);
|
||||
|
||||
Wire.beginTransmission(devID);
|
||||
Wire.write(0xA5); // sys configuration register
|
||||
// DAC ON, Single Conversion, Vout=Fixed by Vext*1.5, Vext=3.6V, Calibrated Output, Diag=on
|
||||
Wire.write(0xFD); //
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if(err != 0){
|
||||
Serial.printf("Writing to register 0xA5 value 0xFD failed = %d\n", err);
|
||||
return false; // fail
|
||||
}
|
||||
|
||||
bool ready = false;
|
||||
uint32_t tick = millis(); // timout
|
||||
while (!ready && (millis() - tick < 1000)) {
|
||||
Wire.beginTransmission(devID);
|
||||
ready = I2C_ERROR_OK == Wire.endTransmission();
|
||||
}
|
||||
if (ready) {
|
||||
Wire.beginTransmission(devID);
|
||||
Wire.write(0xA5);
|
||||
Wire.write(0x0A);
|
||||
err = Wire.endTransmission();
|
||||
if(err != 0){
|
||||
Serial.printf("Writing to register 0xA5 value 0x0A failed = %d\n", err);
|
||||
return false; // fail
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.println("Timeout, Sensor did not respond after first config set.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.println("Reading from 0xA5 failed");
|
||||
return false;
|
||||
}
|
||||
_devID = devID;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool XGZP::read(float * reading) {
|
||||
if ((! _devID ) || ( *reading == NULL )) {
|
||||
Serial.println("Not initialized or no return value location, returning");
|
||||
if (*reading != NULL) *reading = NAN;
|
||||
return false;
|
||||
}
|
||||
|
||||
float XGZPC_Value = 0;
|
||||
bool ready = false;
|
||||
uint32_t tick = millis();
|
||||
while (!ready && (millis() - tick < 1000)) { // Wait upto 1sec for conversion to complete
|
||||
Wire.beginTransmission(_devID);
|
||||
Wire.write(0x02); // status register
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err == I2C_ERROR_OK) {
|
||||
uint8_t count = Wire.requestFrom(_devID, (uint8_t) 1); // get status byte
|
||||
if (count==1) { // got data
|
||||
uint8_t status = Wire.read();
|
||||
ready = (status & 0x01) == 0x01; // data ready!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
Wire.beginTransmission(_devID);
|
||||
Wire.write(0x06); // data register
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err == I2C_ERROR_OK) {
|
||||
uint8_t count = Wire.requestFrom(_devID, (uint8_t) 3); // get data
|
||||
if (count == 3) { // got data
|
||||
XGZPC_Value = Wire.read() * 65536.0 + Wire.read() * 256.0 + Wire.read();
|
||||
XGZPC_Value = XGZPC_Value / 8.0;
|
||||
Serial.print("Pa Value: ");
|
||||
Serial.println(XGZPC_Value);
|
||||
|
||||
XGZPC_Value = XGZPC_Value / 6895.0;
|
||||
|
||||
*reading = XGZPC_Value;
|
||||
Wire.beginTransmission(_devID); // start next sample?
|
||||
Wire.write(0x30);
|
||||
Wire.write(0x0a); // Data and Temp conversion, Single shot, immediate
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err != 0) {
|
||||
Serial.printf(" next Sample start failed? i2cError = %d\n", err);
|
||||
return true; // data valid, next sample will be a problem.
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Serial.println("Read data failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Serial.println("setData address failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else{
|
||||
Wire.beginTransmission(_devID); // start next sample?
|
||||
Wire.write(0x30);
|
||||
Wire.write(0x0a); // Data and Temp conversion, Single shot, immediate
|
||||
uint8_t err = Wire.endTransmission();
|
||||
if (err != 0) {
|
||||
Serial.printf(" Next Sample start failed? i2cError = %d\n", err);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
39
firmware/pressure_digital/XGZP.h
Normal file
39
firmware/pressure_digital/XGZP.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
Copyright 2019 stickbreaker@github
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef XGZP_h
|
||||
#define XGZP_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
class XGZP {
|
||||
|
||||
public:
|
||||
XGZP();
|
||||
|
||||
bool begin( uint8_t devID = 0x6D );
|
||||
bool read( float * reading);
|
||||
private:
|
||||
uint8_t _devID;
|
||||
|
||||
};
|
||||
#endif
|
28
firmware/pressure_digital/pressure_digital.ino
Normal file
28
firmware/pressure_digital/pressure_digital.ino
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <Arduino.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#include "XGZP.h"
|
||||
|
||||
XGZP sensor;
|
||||
|
||||
float value = 1;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
if(!sensor.begin()){
|
||||
Serial.printf("Error initializing Sensor\n Locking up.");
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
sensor.read(&value);
|
||||
|
||||
float corrected = 1.368 * value - 6.4;
|
||||
|
||||
Serial.print(corrected);
|
||||
Serial.println(" PSI");
|
||||
|
||||
delay(250);
|
||||
}
|
24
firmware/relays/relays.ino
Normal file
24
firmware/relays/relays.ino
Normal file
@@ -0,0 +1,24 @@
|
||||
#define RELAY1_PIN 11
|
||||
#define RELAY2_PIN 7
|
||||
|
||||
void setup() {
|
||||
// initialize serial communications at 9600 bps:
|
||||
Serial.begin(9600);
|
||||
|
||||
pinMode(RELAY1_PIN, OUTPUT);
|
||||
pinMode(RELAY2_PIN, OUTPUT);
|
||||
|
||||
digitalWrite(RELAY1_PIN, LOW);
|
||||
digitalWrite(RELAY2_PIN, LOW);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
digitalWrite(RELAY1_PIN, HIGH);
|
||||
delay(500);
|
||||
digitalWrite(RELAY2_PIN, HIGH);
|
||||
delay(500);
|
||||
digitalWrite(RELAY1_PIN, LOW);
|
||||
delay(500);
|
||||
digitalWrite(RELAY2_PIN, LOW);
|
||||
delay(500);
|
||||
}
|
Reference in New Issue
Block a user