#include #ifdef WITH_DEBUGGING_ON #include // debugging support via GDBStub over UART #endif #include "PCA9685.h" extern "C" { #include "user_interface.h" } // OTA & WEB #include #include #include #include "ota.h" #include "wifi_credentials.h" #include "httpserver.h" // BOARD #define ESP12_LED 2 #define NODEMCU_LED 16 // PWM os_timer_t timer1; uint8_t timer_flag = 0; PCA9685 pwmController; void setup_pwm_pca9685(); // WIFI const char* ssid = STASSID; const char* password = STAPSK; // PWM uint32_t dimmtimer = 0; uint16_t time_per_stair = 500; // global parameter: dimmtime per stair [ms] uint8_t direction = 1; uint8_t onoff = 1; void ledsequence(uint8_t direction, uint8_t onoff); uint8_t softstart_led(uint8_t led, uint16_t startval, uint16_t stopval); void timerCallback(void *pArg) { *((int *) pArg) += 1; ledsequence(direction, onoff); // Serial.print("["); // Serial.print(micros()-m); // Serial.print("] timerCallback\n"); // m = micros(); } // HTTP void handleNotFound(); HTTPServer httpServer(80, "/"); // =============================================== void handleNotFound() { String message = "File Not Found\n\n"; message += "URI: "; message += httpServer.uri(); message += "\nMethod: "; message += (httpServer.method() == HTTP_GET) ? "GET" : "POST"; message += "\nArguments: "; message += httpServer.args(); message += "\n"; for (uint8_t i = 0; i < httpServer.args(); i++) { message += " " + httpServer.argName(i) + ": " + httpServer.arg(i) + "\n"; } httpServer.send(404, "text/plain", message); } void setup_pwm_pca9685() { pwmController.resetDevices(); // Software resets all PCA9685 devices on Wire line pwmController.init(B000000); // Address pins A5-A0 set to B000000 pwmController.setPWMFrequency(200); // Default is 200Hz, supports 24Hz to 1526Hz Serial.println(pwmController.getChannelPWM(0)); // Should output 2048, which is 128 << 4 } void setup() { #ifdef WITH_DEBUGGING_ON Serial.begin(460800); gdbstub_init(); #else Serial.begin(115200); #endif Serial.println(F("Booting ....")); pinMode(NODEMCU_LED, OUTPUT); pinMode(ESP12_LED, OUTPUT); Wire.begin(); // Wire must be started first Wire.setClock(1000000); // Supported baud rates are 100kHz, 400kHz, and 1000kHz WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); while (WiFi.waitForConnectResult() != WL_CONNECTED) { Serial.println("Connection Failed! Rebooting..."); delay(5000); ESP.restart(); } Serial.println(""); Serial.print("Connected to "); Serial.println(ssid); Serial.print("IP address: "); Serial.println(WiFi.localIP()); os_timer_setfn(&timer1, timerCallback, &timer_flag); os_timer_arm(&timer1, 20, true); Serial.println("Ready"); Serial.print("IP address: "); Serial.println(WiFi.localIP()); ota_setup(); httpServer.start(); httpServer.onNotFound(handleNotFound); Serial.println("HTTP server started !"); setup_pwm_pca9685(); Serial.println("PCA9685 connected !"); } uint32_t t; #define SP_US(_str,_a) Serial.print(_str); Serial.print(" took: "); Serial.print(_a); Serial.println("µs") #define TIMEIF_US(_str,_f, _l) t=micros(); _f; t=micros()-t; if(t > _l) { SP_US(_str, t); } uint8_t softstart_led(uint8_t led, uint16_t startval, uint16_t stopval){ /* softstart task - get's called at regular intervals (1ms at the moment) - dimms single led (0 - 15, PCA9685 outputs) with linear intervals vom startval to stopval - calculates pwm steps depending on startval, stopval and timeinterval - -> results in constanst speed - returns 1 if led dimming is running - returns 0 if led dimming is finished */ static uint8_t lastled = 255; static float current_pwm = 0; static float stepsize = 1.0; if(led != lastled){ pwmController.setChannelPWM(led, (uint16_t)startval); lastled = led; current_pwm = startval; stepsize = 20*abs(stopval - startval)/(float)time_per_stair; // only valid at 1ms function call interval return 1; } if(current_pwm > stopval - stepsize && current_pwm < stopval + stepsize) return 0; // todo: duty cycle zero! if(startval > stopval){ current_pwm -= stepsize; } else { current_pwm += stepsize; } Serial.println((uint16_t)current_pwm); pwmController.setChannelPWM(led, (uint16_t)current_pwm); return 1; } #define LEDCOUNT 16 void ledsequence(uint8_t direction, uint8_t onoff){ static int8_t led = 0; static uint16_t brightness = 0; static uint16_t lastbrightness = 0; static uint8_t finish = 1; static uint16_t status = 0; uint16_t status_build = 0; status_build |= direction << 8; status_build |= onoff; if(status_build != status){ // check if any parameter changed finish = 0; // set state unfinished -> start action if(direction) led = 0; // reset led counter depending of direction else led = LEDCOUNT-1; if(onoff){ brightness = 2048; // set brightness value depending of on/off lastbrightness = 200; } else{ brightness = 200; lastbrightness = 2048; } status = status_build; // set parameter memory Serial.print("----Status Changed! onoff: "); Serial.print(onoff); Serial.print(" dir: "); Serial.println(direction); } if(!finish){ // finish == 0 -> action pending if(!softstart_led(led,lastbrightness, brightness)){ Serial.print("one LED finished: "); Serial.print(led); Serial.print(" last: "); Serial.print(lastbrightness); Serial.print(" curr: "); Serial.println(brightness); if(direction){ led++; if(led >= LEDCOUNT) { finish = 1; //lastbrightness = brightness; } } else{ led--; if(led < 0){ //lastbrightness = brightness; finish = 1; } } } } } uint32_t _t=0; #define SP_US(_str,_a) Serial.print(_str); Serial.print(" took: "); Serial.print(_a); Serial.println("us") #define TIMEIF_US(_f, _l, _str) _t=micros(); _f; _t=micros()-_t; if(_t > _l) { SP_US(_str, _t); } void loop() { if(millis() > 25000 && onoff == 1 && direction == 1) onoff = 0; if(millis() > 45000 && direction == 1){ onoff = 1; direction = 0; } TIMEIF_US(ArduinoOTA.handle(), 1000, "OTA"); TIMEIF_US(httpServer.handleClient(), 1000, "HTTP"); }