Fixed "Flappy DAC" bug in rev.2.x.x firmware

- Fixed https://github.com/pyr0ball/pyr0piezo/issues/26
  - Changed adjustment logic to be calculated based on Vcc rather than ADC reference, which was causing issues in the mathematical functions, resulting in negative number outputs
 - Migrated to internal vRef, fixed https://github.com/pyr0ball/pyr0piezo/issues/23
 - Eliminated floats, fixing https://github.com/pyr0ball/pyr0piezo/issues/31
  - This required addition of long, however
 - Fixed https://github.com/pyr0ball/pyr0piezo/issues/20
This commit is contained in:
pyr0ball 2019-06-27 01:07:44 -07:00
parent 1d098f184b
commit f745940904
6 changed files with 578 additions and 310 deletions

View file

@ -61,21 +61,21 @@ int GAIN_FACTOR = 2; // Gain adjustment factor. 0=3x, 1=3.5x, 2=4.33x,
#define InitCount 6 // Number of times to blink the LED on start #define InitCount 6 // Number of times to blink the LED on start
int LOOP_DUR = 50; // duration of time between ADC checks and other loop functions int LOOP_DUR = 50; // duration of time between ADC checks and other loop functions
int TRG_DUR = 20; // duration of the Z-axis pulse sent, in ms int TRG_DUR = 20; // duration of the Z-axis pulse sent, in ms
#define senseThrs 1.85 #define senseThrs 1450
#define compThrs 2.54 #define compThrs 2850
int dAdjFac = 1; // adjustment divider. Higher number will cause the DAC output to adjust more slowly.
int Hyst = 20; // Hysteresis value for ADC measurements int Hyst = 20; // Hysteresis value for ADC measurements
#define Vin 5 // input reference voltage
/*------------------------------------------------------------*/ /*------------------------------------------------------------*/
// Debug output toggle. Uncomment to enable // Debug output toggle. Uncomment to enable
#define DEBUG true #define DEBUG true
//#define VERBOSE true
// Headers, variables, and functions // Headers, variables, and functions
#include "pP_pins.h" #include "pP_pins.h"
#include "pP_volatile.h" #include "pP_volatile.h"
#include "pP_functions.h" #include "pP_function.h"
#include "pP_serial.h" #include "pP_serial.h"
// i2c input toggle. Uncomment to enable // i2c input toggle. Uncomment to enable
@ -96,11 +96,6 @@ void setup() {
pinMode(GADJ_R3, INPUT); // declare input to break pull to ground pinMode(GADJ_R3, INPUT); // declare input to break pull to ground
Serial.begin(9600); Serial.begin(9600);
// Uncomment the following lines to use PCInt pins instead of hardware interrupt
//#include <PinChangeInterrupt.h>
//attachPCINT(digitalPinToPCINT(Z_TRG), pulse, FALLING);
// Uncomment the followoing line to use hardware interrupt pin
attachInterrupt(digitalPinToInterrupt(Z_TRG), pulse, FALLING); attachInterrupt(digitalPinToInterrupt(Z_TRG), pulse, FALLING);
Serial.println("Initializing Pyr0-Piezo Sensor..."); Serial.println("Initializing Pyr0-Piezo Sensor...");
@ -127,26 +122,21 @@ void loop() {
// Set any new parameters from serial input // Set any new parameters from serial input
updateParams(); updateParams();
// Check voltage of first and second stages and compare against thresholds
VComp = analogRead(VCOMP_SENSE_PIN);
diffCompL = (VComp - compInt) - Hyst;
diffCompH = (compInt - VComp) - Hyst;
VAdj = analogRead(V_FOLLOW_PIN);
diffAdjL = (VAdj - senseInt) - Hyst;
diffAdjH = (senseInt - VAdj) - Hyst;
// Set the amplification gain factor // Set the amplification gain factor
adjustGain(); adjustGain();
// Check voltage of first and second stages and compare against thresholds
adjustVin();
VComp = analogRead(VCOMP_SENSE_PIN);
VAdj = analogRead(V_FOLLOW_PIN);
// Voltage Follower adjustment // Voltage Follower adjustment
if (diffAdjL > 0 || diffAdjH > 0) { if (VLast > Hyst || VLast < -Hyst) {
adjustFollow(); adjustFollow();
} }
// Voltage Comparator adjustment // Voltage Comparator adjustment
if (diffCompL > 0 || diffCompH > 0) { if (VLast > Hyst || VLast > -Hyst) {
adjustComp(); adjustComp();
} }

View file

@ -0,0 +1,142 @@
/*
pyr0-piezo functions library
Created by Alan "pyr0ball" Weinstock 6/26/2019
*/
/*------------------------------------------------*/
void pulse() {
digitalWrite(TRG_OUT, LOW);
sensorHReading = 1;
delay(TRG_DUR);
digitalWrite(TRG_OUT, HIGH);
}
/*------------------------------------------------*/
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
/*------------------------------------------------*/
void adjustVin() {
VOld = Vin;
Vin = readVcc(), DEC;
senseLong = senseThrs * 1024L;
compLong = compThrs * 1024L;
senseInt = (long long) senseLong / Vin;
compInt = (long long) compLong / Vin;
senseInt = (int) senseInt;
compInt = (int) compInt;
}
/*------------------------------------------------*/
void adjustFollow() {
/* Compares diffs of threshold vs read value
if positive, adjusts the follower to within
the range set above*/
ADJ_FOLLOW = (senseInt / 4);
// Analog output (PWM) of duty cycle
analogWrite(V_FOL_PWM, ADJ_FOLLOW);
}
/*------------------------------------------------*/
void adjustComp() {
ADJ_COMP = (compInt / 4);
analogWrite(VCOMP_PWM, ADJ_COMP);
}
/*------------------------------------------------*/
void calibrateAlert() {
VLast = VOld - Vin;
if (VLast > Hyst || VLast < -Hyst ) {
ERR_STATE = 1;
}
}
/*------------------------------------------------*/
void adjustGain() {
if (GAIN_FACTOR == 0) {
pinMode(GADJ_R3, INPUT);
pinMode(GADJ_R2, INPUT);
pinMode(GADJ_R1, INPUT);
pinMode(GADJ_R0, INPUT);
ERR_STATE = 0;
}
else if (GAIN_FACTOR > 0) {
pinMode(GADJ_R3, OUTPUT);
digitalWrite(GADJ_R3, LOW);
pinMode(GADJ_R2, INPUT);
pinMode(GADJ_R1, INPUT);
pinMode(GADJ_R0, INPUT);
ERR_STATE = 0;
}
else if (GAIN_FACTOR > 1) {
pinMode(GADJ_R2, OUTPUT);
digitalWrite(GADJ_R2, LOW);
pinMode(GADJ_R1, INPUT);
pinMode(GADJ_R0, INPUT);
ERR_STATE = 0;
}
else if (GAIN_FACTOR > 2) {
pinMode(GADJ_R1, OUTPUT);
digitalWrite(GADJ_R1, LOW);
pinMode(GADJ_R0, INPUT);
ERR_STATE = 0;
}
else if (GAIN_FACTOR > 3) {
pinMode(GADJ_R0, OUTPUT);
digitalWrite(GADJ_R0, LOW);
ERR_STATE = 0;
}
}
/*------------------------------------------------*/
void checkError () {
if (ERR_STATE == 1) {
digitalWrite(ERR_LED, BlinkState);
BlinkState = !BlinkState;
}
else if (ERR_STATE == 0) {
BlinkState = LOW;
digitalWrite(ERR_LED, BlinkState);
}
}
/*------------------------------------------------*/
// #endif

View file

@ -1,3 +1,5 @@
#include <Wire.h>
/*------------------------------------------------*/ /*------------------------------------------------*/
#ifdef I2C #ifdef I2C

View file

@ -1,3 +1,127 @@
/*------------------------------------------------*/
void parseData() {
// split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(inputBuffer,","); // get the first part - the string
strcpy(serialMessageIn, strtokIndx); // copy it to serialMessageIn
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
serialInt = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
serialFloat = atof(strtokIndx); // convert this part to a float
}
/*------------------------------------------------*/
void identifyMarkers() {
char x = Serial.read();
// char y = Wire.read();
if (x == endMarker) {
readInProgress = false;
serialIncoming = true;
inputBuffer[bytesRecvd] = 0;
parseData();
}
else if(readInProgress) {
inputBuffer[bytesRecvd] = x;
bytesRecvd ++;
if (bytesRecvd == buffSize) {
bytesRecvd = buffSize - 1;
}
}
else if (x == startMarker) {
bytesRecvd = 0;
readInProgress = true;
}
#ifdef I2C
if (y == endMarker) {
readInProgress = false;
serialIncoming = true;
inputBuffer[bytesRecvd] = 0;
parseData();
}
if(readInProgress) {
inputBuffer[bytesRecvd] = y;
bytesRecvd ++;
if (bytesRecvd == buffSize) {
bytesRecvd = buffSize - 1;
}
}
if (y == startMarker) {
bytesRecvd = 0;
readInProgress = true;
}
#endif
}
/*------------------------------------------------*/
void updateTrigDuration() {
if (serialInt >= 0) {
TRG_DUR = serialInt;
}
}
/*------------------------------------------------*/
void updateGainFactor() {
if (serialInt >= 0) {
GAIN_FACTOR = serialInt;
}
}
/*------------------------------------------------*/
void updateVComp() {
if (serialInt >= 0) {
compInt = (serialFloat * 1024) / Vin;
//senseInt = compInt; // syncing these params til #24 is fixed
}
}
/*------------------------------------------------*/
void updateVAdj() {
if (serialInt >= 0) {
senseInt = (serialFloat * 1024) / Vin;
//compInt = senseInt; // syncing these params til #24 is fixed
}
}
/*------------------------------------------------*/
void updateHysteresis() {
if (serialInt >= 0) {
Hyst = serialInt;
}
}
/*------------------------------------------------*/
/*------------------------------------------------*/
void updateParams() {
if (strcmp(serialMessageIn, "TRG_D") == 0) {
updateTrigDuration();
}
else if (strcmp(serialMessageIn, "GAIN_F") == 0) {
updateGainFactor();
}
else if (strcmp(serialMessageIn, "VCOMP") == 0) {
updateVComp();
}
else if (strcmp(serialMessageIn, "VADJ") == 0) {
updateVAdj();
}
}
void serialInput() { void serialInput() {
// receive data from Serial and save it into inputBuffer // receive data from Serial and save it into inputBuffer
@ -13,10 +137,14 @@ void serialInput() {
/*------------------------------------------------*/ /*------------------------------------------------*/
void serialReply() { void serialReply() {
if (serialIncoming) { #ifndef VERBOSE
serialIncoming = false; if (serialIncoming) {
serialIncoming = false;
#endif
#ifdef DEBUG #ifdef DEBUG
Serial.print("Comp Reference:"); Serial.print("Vcc:");
Serial.println(Vin);
Serial.print("Comp Sense:");
Serial.print(VComp); Serial.print(VComp);
Serial.print(" "); Serial.print(" ");
Serial.print("Comparator State:"); Serial.print("Comparator State:");
@ -50,5 +178,7 @@ void serialReply() {
Serial.print("Error State:"); Serial.print("Error State:");
Serial.println(ERR_STATE); Serial.println(ERR_STATE);
Serial.println("------------------"); Serial.println("------------------");
#ifndef VERBOSE
} }
#endif
} }

View file

@ -4,18 +4,22 @@ volatile int ADJ_FOLLOW = 0; // Variable for Follower adjustment
volatile int ADJ_COMP = 0; // Variable for Comparator adjustment volatile int ADJ_COMP = 0; // Variable for Comparator adjustment
volatile int ERR_STATE = 0; volatile int ERR_STATE = 0;
// Convert float to integer for adjustment functions int Vin = 5000; // input reference voltage in millivolts (multiply V by 1000)
int senseInt = (senseThrs * 1024) / Vin; // Voltage Follower upper converted to adg interger int VOld = 5000; // Variable to store previous cycle's Vin
int compInt = (compThrs * 1024) / Vin; // Upper threshold of Comparator before adjustment int VLast = 0;
// Convert threshold values based on the input voltage
long senseLong = senseThrs * 1024L;
long compLong = compThrs * 1024L;
long senseInt = senseLong / Vin;
long compInt = compLong / Vin;
// Voltage Comparator Adjustment parameters // Voltage Comparator Adjustment parameters
//float VCompRef = 0.00; // variable to store the float value read from the comparator reference
int VComp = 0; int VComp = 0;
int diffCompL = VComp - compInt; int diffCompL = VComp - compInt;
int diffCompH = compInt - VComp; int diffCompH = compInt - VComp;
// Voltage Follower Adjustment parameters // Voltage Follower Adjustment parameters
//float vAdjRead = 0.00; // variable to store the value read from the follower
int VAdj = 0; int VAdj = 0;
int diffAdjL = VAdj - senseInt; int diffAdjL = VAdj - senseInt;
int diffAdjH = senseInt - VAdj; int diffAdjH = senseInt - VAdj;