From 69e1e869a554a94fcb95e12b09dd94dbce5586e7 Mon Sep 17 00:00:00 2001 From: Simon Schmidt Date: Fri, 25 Jun 2021 19:14:30 +0200 Subject: [PATCH] old pwm --- include/pwm.h | 44 ++++++++++++ src/pwm.cpp | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 include/pwm.h create mode 100644 src/pwm.cpp diff --git a/include/pwm.h b/include/pwm.h new file mode 100644 index 0000000..19c957e --- /dev/null +++ b/include/pwm.h @@ -0,0 +1,44 @@ +#pragma once + +#include "PCA9685.h" + +#define SENSOR1 15 +#define SENSOR2 12 + +#define INT_TIME 20 // interrupt intervall [ms] +class Treppe { + private: + uint8_t stairs; + uint16_t time_per_stair = 200; // dimmtime per stair [ms] + uint16_t idle_brightness = 0; + uint16_t active_brightness = 1048; + + uint8_t direction = 0; + uint8_t switch_direction = 0; + uint8_t state = 0; + uint8_t switch_state = 0; + uint8_t finish = 1; + + // initialize with i2c-Address 0, use Wire Library + PCA9685 pwmController; + uint8_t softstart_led(uint8_t led, uint16_t startval, uint16_t stopval); + void ledsequence(); + + public: + Treppe(uint8_t _stairs) : stairs(_stairs){} + void task(); // call periodically + + void setup(); + + // Parameter section + uint16_t setIdle(uint16_t _idle_brightness); + uint16_t setActive(uint16_t _active_brightness); + uint16_t setTime(uint16_t _time_per_stair); + + // Runtime Parameter section + uint8_t setDirection(uint8_t _direction); + uint8_t setState(uint8_t _state); + + uint8_t getState() { return state;}; + uint8_t getDirection() {return direction;}; +}; \ No newline at end of file diff --git a/src/pwm.cpp b/src/pwm.cpp new file mode 100644 index 0000000..13c7397 --- /dev/null +++ b/src/pwm.cpp @@ -0,0 +1,183 @@ +#include "pwm.h" + +uint8_t Treppe::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 = INT_TIME*abs(stopval - startval)/(float)time_per_stair; // only valid at 1ms function call interval + return 1; + } + + if(startval > stopval){ + current_pwm -= stepsize; + } + else { + current_pwm += stepsize; + } + Serial.println((uint16_t)current_pwm); + pwmController.setChannelPWM(led, (uint16_t)current_pwm); + if(current_pwm > stopval - stepsize && current_pwm < stopval + stepsize){ + if(stopval == 0) pwmController.setChannelPWM(led, 0); + return 0; + } + return 1; +} + +void Treppe::ledsequence(){ + static int8_t led = 0; + static uint16_t brightness = 0; + static uint16_t lastbrightness = 0; + static uint16_t status = 0; + uint16_t status_build = 0; + status_build |= direction << 8; + status_build |= state; + 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 = stairs-1; + if(state){ + brightness = active_brightness; // set brightness value depending of on/off + lastbrightness = idle_brightness; + } + else{ + brightness = idle_brightness; + lastbrightness = active_brightness; + } + status = status_build; // set parameter memory + Serial.print("----Status Changed! onoff: "); + Serial.print(state); + 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 >= stairs) { + finish = 1; + //lastbrightness = brightness; + } + } + else{ + led--; + if(led < 0){ + //lastbrightness = brightness; + finish = 1; + } + } + } + } +} + +void Treppe::setup(){ + pwmController.resetDevices(); + + // Deactive PCA9685 Phase Balancer due to LED Flickering + // https://github.com/NachtRaveVL/PCA9685-Arduino/issues/15 + // see also lib/PCA9685-Arduin/PCA9685.h:204 + pwmController.init(PCA9685_PhaseBalancer_None); + pwmController.setPWMFrequency(200); + pwmController.setAllChannelsPWM(idle_brightness); + + pinMode(SENSOR1, INPUT); + pinMode(SENSOR2, INPUT); + Serial.println("Hello from Treppe"); + Serial.print("Treppe: initial parameters: stairs="); + Serial.println(stairs); +} +void Treppe::task(){ + + if(finish){ + direction = switch_direction; + state = switch_state; + } + static uint8_t last_sensor_state[2] = {0,0}; + uint8_t current_sensor_state[2] = {0,0}; + current_sensor_state[0] = digitalRead(SENSOR1); + current_sensor_state[1] = digitalRead(SENSOR2); + + if(current_sensor_state[0] && !last_sensor_state[0] && state == 0){ + setDirection(1); + setState(1); + } + + if(current_sensor_state[1] && !last_sensor_state[1] && state == 0){ + setDirection(0); + setState(1); + } + + // first switch - off approach, use timer later + if(!current_sensor_state[0] && last_sensor_state[0] && state == 1){ + setDirection(1); + setState(0); + } + + if(!current_sensor_state[1] && last_sensor_state[1] && state == 1){ + setDirection(0); + setState(0); + } + + last_sensor_state[0] = current_sensor_state[0]; + last_sensor_state[1] = current_sensor_state[1]; + ledsequence(); + +} + +uint16_t Treppe::setIdle(uint16_t _idle_brightness){ + idle_brightness = _idle_brightness; + Serial.println("Treppe: idle brightness changed!"); + return idle_brightness; +} +uint16_t Treppe::setActive(uint16_t _active_brightness){ + active_brightness = _active_brightness; + Serial.println("Treppe: active brightness changed!"); + return active_brightness; +} +uint16_t Treppe::setTime(uint16_t _time_per_stair){ + time_per_stair = _time_per_stair; + Serial.println("Treppe: time changed!"); + return time_per_stair; +} + +uint8_t Treppe::setDirection(uint8_t _direction){ + switch_direction = _direction; + Serial.println("Treppe: Direction changed!"); + if(finish) Serial.println("apply direction request immediately"); + else Serial.println("currently active, dir change afterwards"); + // to do: implement state command variable to determine dimm-state + return switch_direction; +} + +uint8_t Treppe::setState(uint8_t _state){ + if(state == _state) return 1; + else{ + switch_state = _state; + Serial.println("Treppe: State Request changed!"); + if(finish) Serial.println("apply state request immediately"); + else Serial.println("currently active, state changes after activity"); + } + return 0; +} \ No newline at end of file