diff --git a/vscode/Unendlichkeitsmaschine/include/main.hpp b/vscode/Unendlichkeitsmaschine/include/main.hpp index 6c975b4..52da6c8 100644 --- a/vscode/Unendlichkeitsmaschine/include/main.hpp +++ b/vscode/Unendlichkeitsmaschine/include/main.hpp @@ -19,7 +19,7 @@ #include "capportal.hpp" #include -//#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 \ No newline at end of file diff --git a/vscode/Unendlichkeitsmaschine/include/oled.hpp b/vscode/Unendlichkeitsmaschine/include/oled.hpp index 9c7e09e..eb22b41 100644 --- a/vscode/Unendlichkeitsmaschine/include/oled.hpp +++ b/vscode/Unendlichkeitsmaschine/include/oled.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); diff --git a/vscode/Unendlichkeitsmaschine/src/main.cpp b/vscode/Unendlichkeitsmaschine/src/main.cpp index ab4367e..10e256b 100644 --- a/vscode/Unendlichkeitsmaschine/src/main.cpp +++ b/vscode/Unendlichkeitsmaschine/src/main.cpp @@ -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; diff --git a/vscode/Unendlichkeitsmaschine/src/oled.cpp b/vscode/Unendlichkeitsmaschine/src/oled.cpp index 9ab844c..8a96d5f 100644 --- a/vscode/Unendlichkeitsmaschine/src/oled.cpp +++ b/vscode/Unendlichkeitsmaschine/src/oled.cpp @@ -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 { - static char _runtime_str[26]; - static unsigned long _runtime = 0; + 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) + { 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));