1
0
forked from me/IronOS

Compare commits

..

3 Commits

Author SHA1 Message Date
Ben V. Brown
90599a8ae6 Retune PID, improve response rate slightly. (But slightly more oscillation) 2017-08-02 21:38:42 +10:00
Ben V. Brown
b0264be3c5 Better button auto-repeat 2017-07-30 21:25:27 +10:00
Ben V. Brown
4fb7a70e3c More explicit left handed checks 2017-07-30 20:02:58 +10:00
10 changed files with 181 additions and 83 deletions

View File

@@ -8,40 +8,23 @@
/* Functions for access to data */
extern volatile uint32_t system_Ticks;
void delayMs(uint32_t ticks);
extern volatile uint32_t lastKeyPress;
extern volatile uint32_t lastMovement;
extern volatile uint8_t keyState;
extern volatile uint8_t rawKeys;
inline uint32_t millis() {
return system_Ticks;
}
inline uint32_t getLastButtonPress() {
return lastKeyPress;
}
inline void resetLastButtonPress() {
lastKeyPress = millis();
}
inline void resetButtons() {
keyState = 0;
}
inline uint32_t getLastMovement() {
return lastMovement;
}
inline uint16_t getButtons() {
return keyState;
}
uint8_t getButtons();
uint32_t getLastButtonPress();
inline uint16_t getRawButtons() {
return rawKeys;
}
inline void restoreButtons() {
keyState = getRawButtons();
}
/*IRQ prototypes*/
void NMI_Handler(void);

View File

@@ -18,6 +18,7 @@
#include "Analog.h"
#include "MMA8652FC.h"
#include <string.h>
typedef enum {
STARTUP, //we are sitting on the prompt to push a button
SOLDERING, //Normal operating mode
@@ -31,8 +32,12 @@ typedef enum {
TEMPCAL, //Cal tip temp offset
} operatingModeEnum;
#define SETTINGSOPTIONSCOUNT 11 /*Number of settings in the settings menu*/
//#define PIDTUNING
#ifdef PIDTUNING
#define SETTINGSOPTIONSCOUNT (11+3) /*Number of settings in the settings menu*/
#else
#define SETTINGSOPTIONSCOUNT (11) /*Number of settings in the settings menu*/
#endif
typedef enum {
UVCO = 0,
SLEEP_TEMP,
@@ -46,6 +51,11 @@ typedef enum {
BOOSTMODE,
BOOSTTEMP,
POWERDISPLAY,
#ifdef PIDTUNING
PIDP,
PIDI,
PIDD,
#endif
} settingsPageEnum;
void ProcessUI();

View File

@@ -18,4 +18,5 @@ typedef struct {
int32_t computePID(uint16_t setpoint);
void setupPID(void);
extern pidSettingsType pidSettings;
#endif /* PID_H_ */

View File

@@ -23,7 +23,7 @@ uint16_t readDCVoltage(uint16_t divFactor) {
//This allows us to read it in X10 mode
//Returns temperature in C X10 mode
int16_t readTipTemp() {
static uint32_t rollingAverage[16];
static uint32_t rollingAverage[8];
static uint8_t rIndex = 0;
/*The head has a thermocouple inline with the heater
@@ -54,13 +54,10 @@ int16_t readTipTemp() {
ad_sum = ad_sum - max - min; //remove the two outliers
avg_data = ad_sum / 8; //take the average
rollingAverage[rIndex] = avg_data;
rIndex = (rIndex + 1) % 16;
rIndex = (rIndex + 1) % 8;
return (rollingAverage[0] + rollingAverage[1] + rollingAverage[2]
+ rollingAverage[3] + rollingAverage[4] + rollingAverage[5]
+ rollingAverage[6] + rollingAverage[7] + rollingAverage[8]
+ rollingAverage[9] + rollingAverage[10] + rollingAverage[11]
+ rollingAverage[12] + rollingAverage[13] + rollingAverage[14]
+ rollingAverage[15]) / 16; //get the average
+ rollingAverage[6] + rollingAverage[7]) / 8;
}

View File

@@ -81,7 +81,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
volatile int I2C_TimeOut = 0;
// /* While the bus is busy * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -92,7 +92,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
I2C_GenerateSTART(I2C1, ENABLE);
// / * Test on EV5 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -103,7 +103,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
I2C_Send7bitAddress(I2C1, deviceAddr, I2C_Direction_Transmitter);
// / * Test on EV6 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -114,7 +114,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
I2C_SendData(I2C1, readAddr);
/// * Test on EV8 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -125,7 +125,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
I2C_GenerateSTART(I2C1, ENABLE);
/// * Test on EV5 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -137,7 +137,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
if (numByteToRead == 1) {
/* Wait until ADDR is set */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x0002) != 0x0002) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -155,7 +155,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/* Re-enable IRQs */
__enable_irq();
/* Wait until a data is received in DR register (RXNE = 1) EV7 */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00040) != 0x000040) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -169,7 +169,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/* Set POS bit */
I2C1->CR1 |= CR1_POS_Set;
/* Wait until ADDR is set: EV6 */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x0002) != 0x0002) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -186,7 +186,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/*Re-enable IRQs */
__enable_irq();
/* Wait until BTF is set */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00004) != 0x000004) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -210,7 +210,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
else { //numByteToRead > 2
// * Test on EV6 and clear it * /
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while (!I2C_CheckEvent(I2C1,
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) {
if (I2C_TimeOut-- <= 0) {
@@ -223,7 +223,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
if (numByteToRead != 3) {
/* Poll on BTF to receive data because in polling mode we can not guarantee the
EV7 software sequence is managed before the current byte transfer completes */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00004) != 0x000004) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -239,7 +239,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/* it remains to read three data: data N-2, data N-1, Data N */
if (numByteToRead == 3) {
/* Wait until BTF is set: Data N-2 in DR and data N -1 in shift register */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00004) != 0x000004) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -263,7 +263,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
/* Increment */
pBuffer++;
/* Wait until RXNE is set (DR contains the last data) */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->SR1 & 0x00040) != 0x000040) {
if (I2C_TimeOut-- <= 0) {
return 1;
@@ -278,7 +278,7 @@ int I2C_Master_Read(uint8_t deviceAddr, uint8_t readAddr, uint8_t* pBuffer,
}
/* Make sure that the STOP bit is cleared by Hardware before CR1 write access */
I2C_TimeOut = 3000;
I2C_TimeOut = 1000;
while ((I2C1->CR1 & 0x200) == 0x200) {
if (I2C_TimeOut-- <= 0) {
return 1;

View File

@@ -3,9 +3,10 @@
#include "I2C.h"
volatile uint32_t system_Ticks;
volatile uint32_t lastKeyPress; //millis() at the last button event
volatile uint8_t keyState; //tracks the button status
volatile uint32_t BkeyChange; //millis() at the last button event
volatile uint32_t AkeyChange;
volatile uint8_t rawKeys;
volatile uint8_t LongKeys;
volatile uint32_t lastMovement; //millis() at last movement event
//Delay in milliseconds using systemTick
@@ -14,6 +15,89 @@ void delayMs(uint32_t ticks) {
while (millis() < endtime)
;
}
uint32_t getLastButtonPress() {
if (BkeyChange > AkeyChange)
return BkeyChange;
return AkeyChange;
}
uint8_t getButtons() {
//We want to check the times for the lat buttons & also the rawKeys state
//If a key has just gone down, rawKeys & KEY ==1
uint8_t out = 0;
if (millis() - AkeyChange > 100) {
if (LongKeys & BUT_A) {
if (rawKeys & BUT_A) {
if (millis() - AkeyChange > 800) {
out |= BUT_A;
AkeyChange = millis();
LongKeys &= ~BUT_A;
LongKeys |= (BUT_A << 2);
}
} else {
LongKeys &= ~BUT_A;
LongKeys &= ~(BUT_A << 2);
}
} else if (LongKeys & (BUT_A << 2)) {
if (rawKeys & BUT_A) {
if (millis() - AkeyChange > 100) {
out |= BUT_A;
AkeyChange = millis();
}
} else {
LongKeys &= ~BUT_A;
LongKeys &= ~(BUT_A << 2);
}
} else {
if (rawKeys & BUT_A) {
//The key is down
out |= BUT_A;
LongKeys |= BUT_A;
} else {
//The key has been lifted
LongKeys &= ~BUT_A;
LongKeys &= ~(BUT_A << 2);
}
}
}
if (millis() - BkeyChange > 100) {
if (LongKeys & BUT_B) {
if (rawKeys & BUT_B) {
if (millis() - BkeyChange > 800) {
out |= BUT_B;
BkeyChange = millis();
LongKeys |= (BUT_B << 2);
LongKeys &= ~BUT_B;
}
} else {
LongKeys &= ~BUT_B;
LongKeys &= ~(BUT_B << 2);
}
} else if (LongKeys & (BUT_B << 2)) {
if (rawKeys & BUT_B) {
if (millis() - BkeyChange > 100) {
out |= BUT_B;
BkeyChange = millis();
}
} else {
LongKeys &= ~BUT_B;
LongKeys &= ~(BUT_B << 2);
}
} else {
if (rawKeys & BUT_B) {
//The key is down
out |= BUT_B;
LongKeys |= BUT_B;
} else {
//The key has been lifted
LongKeys &= ~BUT_B;
LongKeys &= ~(BUT_B << 2);
}
}
}
return out;
}
void NMI_Handler(void) {
;
@@ -57,23 +141,19 @@ void EXTI9_5_IRQHandler(void) {
//Line 5 == movement
if (EXTI_GetITStatus(EXTI_Line9) != RESET) {
if (GPIO_ReadInputDataBit(GPIOA, KEY_A) == SET) {
keyState &= ~(BUT_A);
rawKeys &= ~BUT_A;
} else {
keyState |= BUT_A;
rawKeys |= BUT_A;
lastKeyPress = millis();
}
AkeyChange = millis();
EXTI_ClearITPendingBit(EXTI_Line9);
} else if (EXTI_GetITStatus(EXTI_Line6) != RESET) {
if (GPIO_ReadInputDataBit(GPIOA, KEY_B) == SET) {
keyState &= ~(BUT_B);
rawKeys &= ~BUT_B;
} else {
keyState |= BUT_B;
rawKeys |= BUT_B;
lastKeyPress = millis();
}
BkeyChange = millis();
EXTI_ClearITPendingBit(EXTI_Line6);
} else if (EXTI_GetITStatus(EXTI_Line5) != RESET) { //Movement Event
lastMovement = millis();

View File

@@ -18,7 +18,7 @@ int main(void) {
Clear_Watchdog(); //reset the Watch dog timer
ProcessUI();
DrawUI();
delayMs(50); //Slow the system down a little bit
delayMs(30); //Slow the system down a little bit
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_5) == Bit_RESET) {
lastMovement = millis();
//This is a workaround for the line staying low as the user is still moving. (ie sensitivity is too high for their amount of movement)
@@ -39,13 +39,13 @@ void setup() {
setupPID(); //Init the PID values
readIronTemp(systemSettings.tempCalibration, 0, 0); //load the default calibration value
if (systemSettings.OrientationMode == 2)
Init_Oled(!getOrientation()); //Init the OLED display
Init_Oled(0); //Init the OLED display in RH mode, since accel wont have started up yet
else
Init_Oled(systemSettings.OrientationMode); //Init the OLED display
Init_Oled(systemSettings.OrientationMode); //Init the OLED display
OLED_DrawString("VER 1.16", 8); //Version Number
delayMs(400); //Pause to show version number
delayMs(400); //Pause to show version number
showBootLogoIfavailable();
Start_Watchdog(5000); //start the system watch dog as 5 second timeout
Start_Watchdog(5000); //start the system watch dog as 5 second timeout
}

View File

@@ -26,14 +26,6 @@ settingsPageEnum settingsPage;
void ProcessUI() {
uint8_t Buttons = getButtons(); //read the buttons status
static uint32_t lastModeChange = 0;
if (getRawButtons() && ((millis() - getLastButtonPress()) > 1000)) {
lastKeyPress = millis() - 700;
Buttons = getRawButtons();
} else if (millis() - getLastButtonPress() < 100) {
Buttons = 0;
} else if (Buttons != 0) {
resetButtons();
}
switch (operatingMode) {
case STARTUP:
@@ -182,7 +174,7 @@ void ProcessUI() {
case SLEEP_TEMP:
systemSettings.SleepTemp += 100; //Go up 10C at a time
if (systemSettings.SleepTemp > 3000)
systemSettings.SleepTemp = 1000;//cant sleep higher than 300
systemSettings.SleepTemp = 500; //cant sleep higher than 300 or less than 50
break;
case SLEEP_TIME:
++systemSettings.SleepTime; //Go up 1 minute at a time
@@ -201,7 +193,8 @@ void ProcessUI() {
break;
case SCREENROTATION:
systemSettings.OrientationMode++;
systemSettings.OrientationMode = systemSettings.OrientationMode % 3;
systemSettings.OrientationMode =
systemSettings.OrientationMode % 3;
break;
case MOTIONSENSITIVITY:
@@ -232,6 +225,20 @@ void ProcessUI() {
case POWERDISPLAY:
systemSettings.powerDisplay = !systemSettings.powerDisplay;
break;
#ifdef PIDTUNING
case PIDP:
pidSettings.kp++;
pidSettings.kp %= 20;
break;
case PIDI:
pidSettings.ki++;
pidSettings.ki %= 10;
break;
case PIDD:
pidSettings.kd++;
pidSettings.kd %= 30;
break;
#endif
default:
break;
}
@@ -481,7 +488,7 @@ void DrawUI() {
if (systemSettings.powerDisplay) {
//We want to draw in a neat little bar graph of power being pushed to the tip
//ofset 11
uint16_t count = getIronTimer() / (30000 / 28);
uint16_t count = getIronTimer() / (1000 / 28);
if (count > 28)
count = 28;
OLED_DrawWideChar((count), 6);
@@ -648,7 +655,22 @@ void DrawUI() {
break;
}
break;
#ifdef PIDTUNING
case PIDP:
OLED_DrawString("PIDP ", 5);
OLED_DrawThreeNumber(pidSettings.kp, 5);
break;
case PIDI:
OLED_DrawString("PIDI ", 5);
OLED_DrawThreeNumber(pidSettings.ki, 5);
break;
case PIDD:
OLED_DrawString("PIDD ", 5);
OLED_DrawThreeNumber(pidSettings.kd, 5);
break;
#endif
default:
break;
}
}

View File

@@ -141,6 +141,7 @@ void GPIO_Init_OLED(void) {
Description: Initializes the Oled screen
*******************************************************************************/
void Init_Oled(uint8_t leftHanded) {
currentOrientation = leftHanded;
u8 param_len;
OLED_RST();
@@ -148,11 +149,11 @@ void Init_Oled(uint8_t leftHanded) {
OLED_ACT(); //Toggling reset to reset the oled
delayMs(5);
param_len = 46;
if (leftHanded) {
if (leftHanded == 1) {
OLED_Setup_Array[11] = 0xC8;
OLED_Setup_Array[19] = 0xA1;
displayOffset = 0;
} else {
} else if (leftHanded == 0) {
OLED_Setup_Array[11] = 0xC0;
OLED_Setup_Array[19] = 0x40;
displayOffset = 32;
@@ -284,6 +285,8 @@ void OLED_DrawSymbol(uint8_t x, uint8_t symbol) {
}
void OLED_SetOrientation(uint8_t ori) {
if (ori > 1)
return;
if (ori != currentOrientation) {
Init_Oled(ori);
}

View File

@@ -7,38 +7,40 @@
#include "PID.h"
#define MAXPIDOUTPUT 50000
//MAXPIDOUTPUT is the maximum time duration we can support for the irons output, as anything longer than this will be cut off by the next PID iteration
pidSettingsType pidSettings;
//This function computes the new value for the ON time of the system
//This is the return value from this function
int32_t computePID(uint16_t setpoint) {
int32_t ITerm = 0;
static int16_t lastReading = 0;
uint16_t currentReading = readIronTemp(0, 1,setpoint); //get the current temp of the iron
static int32_t ITerm = 0; //Used to store the integral error
static int16_t lastError = 0;
uint16_t currentReading = readIronTemp(0, 1, setpoint); //get the current temp of the iron
int16_t error = (int16_t) setpoint - (int16_t) currentReading; //calculate the error term
ITerm += (pidSettings.ki * error);
if (ITerm > MAXPIDOUTPUT/2)
ITerm = MAXPIDOUTPUT/2;
else if (ITerm < 0)
ITerm = 0; //cap at 0 since we cant force the iron to cool itself :)
int16_t DInput = (error - lastError) / 10; //compute the input to the D term
int16_t DInput = (currentReading - lastReading); //compute the input to the D term
int32_t output = (pidSettings.kp * error) + (ITerm)
ITerm += ((error) / 20);
if (ITerm > 300)
ITerm = 0; //Prevents this accumulating too much during inital heatup
else if (ITerm < 0)
ITerm = 0; //Cap at 0 as we can't force cool
if (DInput > 1000)
DInput = 0;
int32_t output = (pidSettings.kp * error) + (ITerm * pidSettings.ki)
- (pidSettings.kd * DInput);
if (output > MAXPIDOUTPUT)
output = MAXPIDOUTPUT;
else if (output < 0)
output = 0;
lastReading = currentReading; //storing values for next iteration of the loop
lastError = error;
return output;
}
/*Sets up the pid values*/
/*Sets up the pid values to defaults*/
void setupPID(void) {
pidSettings.kp = 15;
pidSettings.ki = 2;
pidSettings.kd = 3;
pidSettings.kp = 8;
pidSettings.ki = 1;
pidSettings.kd = 0; //Not using D atm
}