pid seems to work now
This commit is contained in:
parent
c390c741d2
commit
57580f4436
4 changed files with 68 additions and 130 deletions
|
@ -19,7 +19,7 @@
|
|||
#include "capportal.hpp"
|
||||
#include <esp32-hal-timer.h>
|
||||
|
||||
//#define HAS_MQTT
|
||||
#define HAS_MQTT
|
||||
#ifdef HAS_MQTT
|
||||
#include "mqtt.hpp"
|
||||
#include "json.hpp"
|
||||
|
@ -56,13 +56,13 @@ Oled display;
|
|||
|
||||
const unsigned long MAX_TIME_PER_TURN_MS = 600;
|
||||
const unsigned long UPDATE_TURN_VALUES_EVERY_MS = 1000;
|
||||
const unsigned long UPDATE_ESC_EVERY_MS = 500;
|
||||
const unsigned long UPDATE_ESC_EVERY_MS = 200;
|
||||
|
||||
const uint8_t HALL_SENSORS_COUNT = 8; // input, sec, min, hour, day, week, month, year
|
||||
const uint8_t ALL_DATA_COUNT = HALL_SENSORS_COUNT;
|
||||
|
||||
const uint8_t HALL_TICKS_PER_TURN = 4;
|
||||
const uint8_t HALL_NR_TURN = 4;
|
||||
const uint8_t HALL_NR_TURN = 2;
|
||||
const uint8_t HALL_MIN_PULSE_MS = 50;
|
||||
|
||||
volatile DataStruct AllData[ALL_DATA_COUNT];
|
||||
|
@ -89,10 +89,8 @@ const char ** Hall_units = Data_units;
|
|||
const float * Hall_units_factor = Data_units_factor;
|
||||
|
||||
const uint8_t LED_BUILTIN = 2;
|
||||
const uint8_t POTI_PIN = 36; // never use ADC2 (GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27) if Wifi is active ... use ADC1 instead (GPIO32-GPIO39)
|
||||
const uint8_t ESC_PIN = 16;
|
||||
|
||||
|
||||
const uint8_t HALL1_PIN = 34;
|
||||
const uint8_t HALL2_PIN = 35;
|
||||
const uint8_t HALL3_PIN = 32;
|
||||
|
@ -102,13 +100,11 @@ const uint8_t HALL6_PIN = 26;
|
|||
const uint8_t HALL7_PIN = 27;
|
||||
const uint8_t HALL8_PIN = 14;
|
||||
|
||||
const uint8_t TIME_PER_ROUND_VALS = 10;
|
||||
const uint8_t TIME_PER_ROUND_VALS = 20;
|
||||
|
||||
const uint16_t MIN_SPEED = 500;
|
||||
const uint16_t MAX_SPEED = 5000;
|
||||
const uint8_t MAX_ESC_SPEED = 180;
|
||||
const uint8_t MIN_ESC_SPEED = 0;
|
||||
const uint16_t MAX_POTI_VALUE = 4095;
|
||||
const uint16_t JITTER_POTI_PERCENT = 10;
|
||||
const uint8_t MIN_ESC_SPEED = 7;
|
||||
|
||||
#endif //MAIN_HPP
|
|
@ -10,11 +10,11 @@ class Oled
|
|||
{
|
||||
private:
|
||||
const unsigned long PAGE_VIEW_TIME_MS = 10000;
|
||||
const uint8_t HALLS_PER_PAGE = 4;
|
||||
const uint8_t MAX_PAGE_NR = HALL2;
|
||||
const uint8_t HALLS_PER_PAGE = 2;
|
||||
const uint8_t MAX_PAGE_NR = HALL4;
|
||||
const uint8_t MIN_PAGE_NR = SPEED;
|
||||
|
||||
enum pages {SPEED, HALL1, HALL2};
|
||||
enum pages {SPEED, HALL1, HALL2, HALL3, HALL4};
|
||||
|
||||
//SSD1306Wire display(0x3c, SDA, SCL);
|
||||
SSD1306Wire *display;
|
||||
|
@ -26,7 +26,7 @@ class Oled
|
|||
uint8_t page_nr = MIN_PAGE_NR;
|
||||
|
||||
void next_page(bool speedchange);
|
||||
void show_page_header( String ipaddr, pages page);
|
||||
void show_page_header( String ipaddr);
|
||||
void show_speed(int speed, int min_speed, int max_speed, double u_min, unsigned long runtime, pages page);
|
||||
void show_halls(volatile DataStruct *HallData, uint8_t hall_sensor_count, pages page);
|
||||
void show_page_footer(pages page);
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
#include "main.hpp"
|
||||
|
||||
int Drehregler; // Ausgabewert des Drehreglers
|
||||
int speed; // Das Wort "Geschwindigkeit" steht als Variable für den Ansteuerungswert am ESC.
|
||||
int last_speed;
|
||||
volatile uint8_t time_per_round_pointer = 0;
|
||||
volatile double time_per_round_ms[TIME_PER_ROUND_VALS];
|
||||
|
||||
|
@ -14,15 +11,14 @@ double integ = 0.0;
|
|||
double derivative = 0.0;
|
||||
double esc_output = 0.0;
|
||||
int ser_esc_output = -1;
|
||||
double ser_speed = 1000;
|
||||
double speed = 1000.0;
|
||||
double last_error = 0.0;
|
||||
int esc_value = 0;
|
||||
double goal_speed = 0;
|
||||
double current_speed = 0;
|
||||
double err = 0;
|
||||
double output = 0.0;
|
||||
double kp = 0.03;
|
||||
double ki = 0.01;
|
||||
double ki = 0.008;
|
||||
double kd = 0.002;
|
||||
|
||||
|
||||
|
@ -42,7 +38,6 @@ void data_generate();
|
|||
void data_store();
|
||||
void data_check();
|
||||
void data_init();
|
||||
void speed_get();
|
||||
void speed_set();
|
||||
|
||||
void PID();
|
||||
|
@ -117,20 +112,15 @@ void setup()
|
|||
attachInterrupt(digitalPinToInterrupt(HALL8_PIN), ISR_HALL8, FALLING);
|
||||
|
||||
#endif
|
||||
|
||||
Serial.println(" Auf gehts ... ");
|
||||
ESC.write(50);
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
capportal.handle();
|
||||
get_serial_cmd();
|
||||
data_generate();
|
||||
count_secs(&run_time);
|
||||
speed_get();
|
||||
speed_set();
|
||||
data_check();
|
||||
data_store();
|
||||
|
@ -170,7 +160,7 @@ void PID()
|
|||
derivative = 0;
|
||||
}
|
||||
|
||||
err = goal_speed - current_speed;
|
||||
err = constrain(speed - current_speed, -100, 100);
|
||||
double int_integ = integ + err;
|
||||
double int_derivative = err - last_error;
|
||||
if(ki != 0)
|
||||
|
@ -265,16 +255,18 @@ unsigned long time_per_round_calc()
|
|||
{
|
||||
for (uint8_t i= 0; i < TIME_PER_ROUND_VALS; i++)
|
||||
{
|
||||
time_per_round_ms[i] = TIME_PER_ROUND_VALS;
|
||||
time_per_round_ms[i] = HALL_NR_TURN*MAX_TIME_PER_TURN_MS;
|
||||
}
|
||||
mid_time = MAX_TIME_PER_TURN_MS;
|
||||
}
|
||||
/*
|
||||
static unsigned long last_mid_time = millis();
|
||||
if(millis() - last_mid_time > 500)
|
||||
{
|
||||
Serial.printf(">turn_time_ms:%d\n>real_values:%d\n", mid_time, real_values);
|
||||
last_mid_time = millis();
|
||||
}
|
||||
*/
|
||||
return(mid_time);
|
||||
}
|
||||
|
||||
|
@ -284,65 +276,12 @@ void speed_set()
|
|||
if(0 == last_esc_write_ms || millis() - last_esc_write_ms > UPDATE_ESC_EVERY_MS)
|
||||
{
|
||||
PID();
|
||||
//Serial.printf(">periodticks0:%d\n>ticks0turntime_ms:%d\n>goal:%06.3f\n>current:%06.3f\n>err:%06.3f\n>integ:%06.3f\n>derive:%06.3f\n>output:%06.3f\n>esc_output:%06.3f\n",
|
||||
// HallData[0].period_ticks, time_per_round_ms[time_per_round_pointer], goal_speed, current_speed, err, integ, derivative, output, esc_output);
|
||||
Serial.printf(">period_ticks:%d\n>time_per_round_last_updated_ms:%d\n>goal_speed:%06.3f\n>current:%06.3f\n>err:%06.3f\n",
|
||||
HallData[0].period_ticks,HallData[0].act_update_ms, goal_speed, current_speed, err);
|
||||
Serial.printf(">speed:%06.3f\n>current:%06.3f\n>esc:%06.3f\n",speed, current_speed, esc_output);
|
||||
ESC.write(esc_output);
|
||||
last_esc_write_ms = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void speed_get()
|
||||
{
|
||||
static uint8_t _count_meas = 0;
|
||||
static int _Drehregler = 0;
|
||||
static unsigned long _last_read_ms = 0;
|
||||
if(ser_speed == -1)
|
||||
{
|
||||
if( millis() - _last_read_ms > 25)
|
||||
{
|
||||
_last_read_ms = millis();
|
||||
int maxDrehregler = 0;
|
||||
int minDrehregler = 0;
|
||||
int sumDrehregler = 0;
|
||||
for(uint8_t i = 0; i<6;i++)
|
||||
{
|
||||
Drehregler = analogRead(POTI_PIN); // Dieser Befehl liest den Wert des Potentiometers am analogen Pin A0 aus und speichert ihn unter der Variablen "Drehregler". Der Wert liegt zwischen 0 und 1023.
|
||||
if(i==0)
|
||||
{
|
||||
maxDrehregler = Drehregler;
|
||||
minDrehregler = Drehregler;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Drehregler < minDrehregler)
|
||||
{
|
||||
minDrehregler = Drehregler;
|
||||
}
|
||||
if(Drehregler > maxDrehregler)
|
||||
{
|
||||
maxDrehregler = Drehregler;
|
||||
}
|
||||
}
|
||||
sumDrehregler = sumDrehregler + Drehregler;
|
||||
}
|
||||
sumDrehregler = sumDrehregler - maxDrehregler - minDrehregler;
|
||||
sumDrehregler = sumDrehregler/4;
|
||||
#ifdef DUMMY_DATA
|
||||
speed = 1000;
|
||||
#else
|
||||
speed = map(sumDrehregler, 0, MAX_POTI_VALUE, MIN_SPEED, MAX_SPEED); // Der "MAP-" Befehl wandelt den Messwert aus der Variablen "Drehregler" um, damit er am ESC verarbeitet werden kann. Der Zahlenbereich 0 bis 1023 wird dabei in einen Zahlenwert zwischen 0 und 180 umgewandelt.
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else{
|
||||
speed = ser_speed;
|
||||
}
|
||||
goal_speed = 1.0 * speed;
|
||||
|
||||
}
|
||||
|
||||
void data_init()
|
||||
{
|
||||
Serial.println("Init internal data ...");
|
||||
|
@ -357,8 +296,6 @@ void data_init()
|
|||
start_time = Store.get_int(EEPROM_NAME_START_EPOCHTIME );
|
||||
Serial.printf("Machine runtime loaded from EPPROM: %lu seconds. Machine was started %s\n", run_time, capportal.localTime(start_time));
|
||||
#endif
|
||||
last_speed = 0;
|
||||
speed = 0;
|
||||
for (uint8_t i= 0; i < TIME_PER_ROUND_VALS; i++)
|
||||
{
|
||||
time_per_round_ms[i] = HALL_NR_TURN*MAX_TIME_PER_TURN_MS;
|
||||
|
@ -383,7 +320,6 @@ void data_init()
|
|||
}
|
||||
#endif
|
||||
AllData[i].act_update_ms = 0;
|
||||
//AllData[i].prev_update_ms = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,6 +354,7 @@ void data_check()
|
|||
else
|
||||
{
|
||||
HallData[nr].value = HallData[nr].unit_factor / mid_time;
|
||||
HallData[nr].value = HallData[nr].value > MAX_SPEED? MAX_SPEED:HallData[nr].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -462,8 +399,8 @@ void get_serial_cmd()
|
|||
Serial.printf("Set ki to %f\n", ki);
|
||||
}
|
||||
else if(command.startsWith("speed=")){
|
||||
ser_speed = command.substring(command.indexOf("=")+1).toDouble();
|
||||
Serial.printf("Set speed to %f\n", ser_speed);
|
||||
speed = command.substring(command.indexOf("=")+1).toDouble();
|
||||
Serial.printf("Set speed to %f\n", speed);
|
||||
}
|
||||
else if(command.startsWith("kd=")){
|
||||
derivative = 0.0;
|
||||
|
@ -519,15 +456,19 @@ void get_serial_cmd()
|
|||
void IRAM_ATTR ISR_HALL1()
|
||||
{
|
||||
const uint8_t hallnr = 0;
|
||||
const unsigned long hall_ticks = HALL_NR_TURN * HALL_TICKS_PER_TURN;
|
||||
const unsigned long hall_time = HALL_NR_TURN * MAX_TIME_PER_TURN_MS;
|
||||
HallData[hallnr].ticks++;
|
||||
HallData[hallnr].period_ticks++;
|
||||
HallData[hallnr].timestamp = run_time;
|
||||
// each 4 ticks is one turn
|
||||
// so we calculate speed each 4 ticks... just in case we check for bigger ...
|
||||
if(HallData[hallnr].period_ticks >= (HALL_NR_TURN * HALL_TICKS_PER_TURN)){
|
||||
if(HallData[hallnr].period_ticks >= hall_ticks ){
|
||||
unsigned long time_ms = millis();
|
||||
unsigned long time_diff_ms = time_ms - HallData[hallnr].act_update_ms;
|
||||
time_diff_ms= time_diff_ms > hall_time?hall_time:time_diff_ms;
|
||||
HallData[hallnr].period_ticks = 0;
|
||||
time_per_round_ms[time_per_round_pointer] = time_ms - HallData[hallnr].act_update_ms;
|
||||
time_per_round_ms[time_per_round_pointer] = time_diff_ms;
|
||||
HallData[hallnr].act_update_ms = time_ms;
|
||||
time_per_round_pointer++;
|
||||
time_per_round_pointer = time_per_round_pointer>TIME_PER_ROUND_VALS?0:time_per_round_pointer;
|
||||
|
|
|
@ -125,7 +125,7 @@ void Oled::show_values(int speed, int min_speed, int max_speed, volatile DataStr
|
|||
_runtime = runtime; //runtime comes in in secs
|
||||
_ipaddr = ipaddr;
|
||||
|
||||
show_page_header(ipaddr, page);
|
||||
show_page_header(ipaddr);
|
||||
show_speed(speed, min_speed, max_speed, _hall[0], _runtime, page );
|
||||
show_halls(HallData, min(local_hall_count,hall_sensors_count), page);
|
||||
show_page_footer(page);
|
||||
|
@ -159,36 +159,25 @@ void Oled::show_page_footer(pages page)
|
|||
display->drawHorizontalLine(_xpos+radius*2-2,63,128 - (_xpos+radius*2));
|
||||
}
|
||||
|
||||
void Oled::show_page_header(String ipaddr, pages page)
|
||||
void Oled::show_page_header(String ipaddr)
|
||||
{
|
||||
xpos = 0;
|
||||
ypos = 0;
|
||||
display->clear();
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
switch(page)
|
||||
if(ipaddr == "0.0.0.0")
|
||||
{
|
||||
case HALL1:
|
||||
case HALL2:
|
||||
display->drawString(0, ypos, "Measured numbers:");
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
break;
|
||||
case SPEED:
|
||||
default:
|
||||
if(ipaddr == "0.0.0.0")
|
||||
{
|
||||
display->drawString(0, ypos, "No WiFi.");
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display->drawString(128,ypos, "x");
|
||||
}
|
||||
else
|
||||
{
|
||||
display->drawString(0, ypos, "IP:" + ipaddr);
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display->drawString(128,ypos, "Y");
|
||||
display->drawString(124,ypos-2, "--");
|
||||
}
|
||||
break;
|
||||
display->drawString(0, ypos, "No WiFi.");
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display->drawString(128,ypos, "x");
|
||||
}
|
||||
else
|
||||
{
|
||||
display->drawString(0, ypos, "IP:" + ipaddr);
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display->drawString(128,ypos, "Y");
|
||||
display->drawString(124,ypos-2, "--");
|
||||
}
|
||||
display->drawHorizontalLine(0,ypos+12, 128);
|
||||
ypos = ypos + 13;
|
||||
|
@ -196,10 +185,34 @@ void Oled::show_page_header(String ipaddr, pages page)
|
|||
|
||||
void Oled::show_speed(int speed, int min_speed, int max_speed, double u_min, unsigned long runtime, pages page)
|
||||
{
|
||||
|
||||
static char _runtime_str[26];
|
||||
static unsigned long _runtime = 0;
|
||||
uint8_t _ypos = ypos;
|
||||
uint8_t _ypos_offset = 0;
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
//display->setFont(ArialMT_Plain_10);
|
||||
//display->drawString(1, _ypos, "Speed:");
|
||||
//display->drawProgressBar(38, _ypos+4, 87, 5 , map(speed, min_speed, max_speed,0,100));
|
||||
//display->setFont(ArialMT_Plain_10);
|
||||
//_ypos=_ypos+9;
|
||||
if(page == SPEED)
|
||||
{
|
||||
display->setFont(ArialMT_Plain_24);
|
||||
_ypos_offset = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
display->setFont(ArialMT_Plain_16);
|
||||
}
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display->drawString(83, _ypos, String(int(u_min)));
|
||||
display->setFont(ArialMT_Plain_16);
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->drawString(85,_ypos+_ypos_offset, "U/min");
|
||||
_ypos=_ypos + 16 + _ypos_offset; //24;
|
||||
if(page == SPEED)
|
||||
{
|
||||
static char _runtime_str[26];
|
||||
static unsigned long _runtime = 0;
|
||||
if( _runtime != runtime || _runtime == 0)
|
||||
{
|
||||
_runtime = runtime;
|
||||
|
@ -218,30 +231,18 @@ void Oled::show_speed(int speed, int min_speed, int max_speed, double u_min, uns
|
|||
uint8_t _runtime_sec = _runtime;
|
||||
sprintf(_runtime_str, "%01dy %02dm %01dw %01dd %02dh %02dm %02ds", _runtime_years, _runtime_month, _runtime_week, _runtime_days, _runtime_hour, _runtime_min, _runtime_sec);
|
||||
}
|
||||
|
||||
uint8_t _ypos = ypos;
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
display->drawString(1, _ypos, "Speed:");
|
||||
display->drawProgressBar(38, _ypos+4, 87, 5 , map(speed, min_speed, max_speed,0,100));
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
_ypos=_ypos+9;
|
||||
display->setFont(ArialMT_Plain_24);
|
||||
display->setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
display->drawString(83, _ypos, String(u_min));
|
||||
display->setFont(ArialMT_Plain_16);
|
||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display->drawString(85,_ypos+8, "U/min");
|
||||
_ypos=_ypos+24;
|
||||
_ypos = _ypos + 5;
|
||||
display->setFont(ArialMT_Plain_10);
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->drawString(64, _ypos, _runtime_str);
|
||||
_ypos = _ypos + 10;
|
||||
}
|
||||
ypos = _ypos;
|
||||
}
|
||||
|
||||
void Oled::show_halls(volatile DataStruct *HallData, uint8_t hall_sensor_count, pages page)
|
||||
{
|
||||
if(page == HALL1 || page == HALL2)
|
||||
if(page == HALL1 || page == HALL2 || page == HALL3 || page == HALL4)
|
||||
{
|
||||
uint8_t hall_start = (page_nr-HALL1)*HALLS_PER_PAGE;
|
||||
uint8_t hall_count = min(HALLS_PER_PAGE, (uint8_t)(hall_sensor_count-hall_start));
|
||||
|
|
Loading…
Add table
Reference in a new issue