From a18f9c6ac57be32603950d945e683654c6133c0b Mon Sep 17 00:00:00 2001 From: Jens Noack Date: Wed, 8 Dec 2021 22:58:58 +0100 Subject: [PATCH] preprefinal --- include/leds.h | 27 ++++++ include/main.h | 14 +-- include/mp3.h | 3 +- include/train.h | 2 +- src/main.cpp | 245 +++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 239 insertions(+), 52 deletions(-) diff --git a/include/leds.h b/include/leds.h index f020681..9c15e5e 100644 --- a/include/leds.h +++ b/include/leds.h @@ -30,6 +30,10 @@ class leds uint16_t _prev_state = 0; Adafruit_NeoPixel * _stripe; + int _tcr_firstPixelHue; + int _tcr_b ; + + uint8_t _s = 0; uint16_t _h = 0; @@ -64,10 +68,13 @@ class leds void setColor(uint32_t color); void rainbowCycle(); bool do_rainbowCycle(); + void theaterChaseRainbow(); }; leds::leds(Adafruit_NeoPixel * stripe, uint32_t * state_flag, uint16_t state_mask, uint16_t H, uint8_t S, unsigned int pixel_first, unsigned int pixel_last ) { + _tcr_firstPixelHue = 0; + _tcr_b = 0; _state_flag = state_flag; _state_mask = state_mask; _h = H; @@ -296,6 +303,26 @@ bool leds::_fade_off() return _fade(false); } +void leds::theaterChaseRainbow() +{ + if((millis() - _last_rainbowcycle) > WAIT_RAINBOWCYCLE_MS) + { + _last_rainbowcycle = millis(); + _tcr_b++; + if(_tcr_b >= 3) + _tcr_b = 0; + clear(); // Set all pixels in RAM to 0 (off) + for(int c=_tcr_b; c<_pixel_nr; c += 3) + { + int hue = _tcr_firstPixelHue + c * 65536L / _pixel_nr; + uint32_t color = _stripe->gamma32(_stripe->ColorHSV(hue)); // hue -> RGB + _pixels[c].color = color; + } + _setLeds(); + _tcr_firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames + } +} + void leds::rainbowCycle() { diff --git a/include/main.h b/include/main.h index c31cbb5..27b6536 100644 --- a/include/main.h +++ b/include/main.h @@ -9,7 +9,7 @@ //#include "eeprom.h" //eeprom flash; -const unsigned long SZENE_TIMEOUT_TO_SET_TO_DEFAULT_MS = 30000; +const unsigned long SZENE_TIMEOUT_TO_SET_TO_DEFAULT_MS = 600000; ///---- OLED ---- @@ -23,12 +23,12 @@ const size_t PIN_MP3_RX = 25 ; //D2; const size_t PIN_MP3_TX = 26 ; //D3; const uint8_t SONG_EINE_INSEL = 1; -const uint8_t SONG_WEIHNACHTSBAECKEREI = 2; -const uint8_t SONG_WEIHNACHTSBAHN = 3; -const uint8_t SONG_OH_TANNEBAUM = 4; -const uint8_t SONG_DISCO_MARYSBOYCHILD = 5; -const uint8_t SONG_DISCO_LASTCHRISTMAS = 6; -const uint8_t SONG_DISCO_DOTHEYKNOWITSCHRISTMAS = 7; +const uint8_t SONG_WEIHNACHTSBAECKEREI = 3; +const uint8_t SONG_WEIHNACHTSBAHN = 5; +const uint8_t SONG_OH_TANNEBAUM = 7; +const uint8_t SONG_DISCO_MARYSBOYCHILD = 9; +const uint8_t SONG_DISCO_LASTCHRISTMAS = 11; +const uint8_t SONG_DISCO_DOTHEYKNOWITSCHRISTMAS = 13; mp3 mp3ply(PIN_MP3_RX, PIN_MP3_TX); diff --git a/include/mp3.h b/include/mp3.h index 9679927..9d51427 100644 --- a/include/mp3.h +++ b/include/mp3.h @@ -102,7 +102,8 @@ unsigned long mp3::is_playing() String answer = player->decodeMP3Answer(); if(answer.indexOf(STARTED_STRING) > -1) { - return(millis() - _play_since_ms); + //return(millis() - _play_since_ms); + return 1; } } Serial.printf("MP3 Player is not playing\n"); diff --git a/include/train.h b/include/train.h index f059bcd..9a7be67 100644 --- a/include/train.h +++ b/include/train.h @@ -92,7 +92,7 @@ void train::set_pwm(uint8_t pwm_value) { } _fade_step = pwm_value; ledcWrite(_pwmchannel, pwm_value); - Serial.printf("PWM '%s' set to value %d\n", _name, pwm_value); + //Serial.printf("PWM '%s' set to value %d\n", _name, pwm_value); } } diff --git a/src/main.cpp b/src/main.cpp index 47adbc0..17f0da1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,12 +18,15 @@ void updateNVS(); unsigned int licht_all_count = 0; unsigned int move_all_count = 0; +unsigned int disco_all_count = 0; unsigned long last_updated_NVS = 0; bool licht_is_fading = false; +bool mp3_isused = false; void setup() { Serial.begin(115200); + randomSeed(analogRead(0)); taster_aussen_licht.begin(); taster_aussen_move.begin(); @@ -40,11 +43,12 @@ void setup() { NVS.begin(); licht_all_count = NVS.getInt("licht"); move_all_count = NVS.getInt("move"); + disco_all_count = NVS.getInt("disco"); moni.init(); moni.setBrigthness(100); - licht_state_flag = LSTERNBILD1 | LSTERNBILD2 | LSTERNBILD3 | LSTERNE1 | LSTERNE2 | LBAUHOF | LBURG | LTANNE; + licht_state_flag = LSTERNBILD1 | LSTERNBILD2 | LSTERNBILD3 | LSTERNE1 | LSTERNE2 | LTANNE; mp3ply.begin(); mp3ply.stop(); @@ -71,8 +75,7 @@ void loop() { taster_abfrage(); set_lichtszene(); set_moveszene(); - licht_is_fading = licht_update(); - + licht_is_fading = licht_update(); } bool next_licht_szene_possible = true; @@ -111,6 +114,8 @@ void set_lichtszene() } if(millis() - szene_overall_time_ms > SZENE_TIMEOUT_TO_SET_TO_DEFAULT_MS) { + szene_overall_time_ms = millis(); + Serial.printf("Setting Licht backt to default night withe Tannenbaum\n"); licht_state_flag = LSTERNBILD1 | LSTERNBILD2 | LSTERNBILD3 | LSTERNE1 | LSTERNE2 | LTANNE; licht_szene = 0; taster_aussen_licht.reset(); @@ -141,7 +146,7 @@ void set_moveszene() } const byte TANNENBAUM_VOL = 20; -const unsigned long TANNENBAUM_PLAY_MUSIC_MS = 60000; +const unsigned long TANNENBAUM_PLAY_MUSIC_MS = 135000; typedef enum {TA_INIT = 0, TA_LIGHT_READY, TA_START_PLAYING ,TA_MIN_PLAYING,TA_PLAYING, TA_STOP_PLAYING, TA_FINSIHED} szene_tanne_t; szene_tanne_t tanne_state = TA_INIT; void szene_oh_tannebaum() @@ -157,9 +162,14 @@ void szene_oh_tannebaum() case TA_LIGHT_READY: if(licht_is_fading == false) { - tanne_state = TA_START_PLAYING; - Serial.printf("All lights are ready for Oh Tannebaum\n"); - mp3ply.play_vol(2, TANNENBAUM_VOL); + if(mp3_isused == true) + tanne_state = TA_FINSIHED; + else{ + mp3_isused = true; + tanne_state = TA_START_PLAYING; + Serial.printf("All lights are ready for Oh Tannebaum\n"); + mp3ply.play_vol(SONG_OH_TANNEBAUM, TANNENBAUM_VOL); + } } break; case TA_START_PLAYING: @@ -176,17 +186,15 @@ void szene_oh_tannebaum() tanne_state = TA_PLAYING; break; case TA_PLAYING: - if(msecs - szene_time_ms > TANNENBAUM_PLAY_MUSIC_MS || taster_aussen_licht.pressed() == true || mp3ply.is_playing() == 0) + if(msecs - szene_time_ms > TANNENBAUM_PLAY_MUSIC_MS || taster_aussen_licht.pressed() == true ) tanne_state = TA_STOP_PLAYING; break; case TA_STOP_PLAYING: if(mp3ply.fade_out() == false) { - //if(mp3ply.is_playing() == 0) - //{ Serial.printf("Oh Tannebaum faded out and stopped\n"); tanne_state = TA_FINSIHED; - //} + mp3_isused = false; } break; case TA_FINSIHED: @@ -306,14 +314,14 @@ void szene_tag_dorf() } } - unsigned int zugunten_error = 0; const unsigned int ZUGUNTEN_MAX_ERROR_COUNT = 5; const unsigned long ZUGUNTEN_DRIVES_TO_STATION_MS = 5000; const unsigned long ZUGUNTEN_STOPPED_AT_STATION_MS = 5000; const unsigned long ZUGUNTEN_MAX_TIME_TO_HOME_MS = 15000; ///timeout time -typedef enum {ZU_INIT = 0, ZU_AT_HOME , ZU_DRIVES_TO_STATION, ZU_STOPPES_AT_STATION, ZU_STOPPED_AT_STATION, ZU_DRIVES_HOME, ZU_STOPPES_AT_HOME} szene_zugunten_t; +typedef enum {ZU_INIT = 0, ZU_AT_HOME , ZU_DRIVES_TO_STATION, ZU_STOPPES_AT_STATION, ZU_STOPPED_AT_STATION, ZU_DRIVES_HOME, ZU_STOPPES_AT_HOME, ZU_STOPPED_PLAYING, ZU_DONE} szene_zugunten_t; szene_zugunten_t zugunten_state = ZU_INIT; +bool mp3_zugunten = false; void move_zugunten() { unsigned long msecs = millis(); @@ -323,9 +331,23 @@ void move_zugunten() Serial.printf("Zugunten fährt\n"); taster_train_unten.reset(); if (zugunten_error > ZUGUNTEN_MAX_ERROR_COUNT) - zugunten_state = ZU_STOPPES_AT_HOME; + { + zugunten_state = ZU_DONE; + Serial.printf("Zugunten . More errors than allowed - will stop here."); + } else + { zugunten_state = ZU_AT_HOME; + if(mp3_isused == false) + { + Serial.printf("Playing Eine Insel\n"); + mp3ply.play_vol(SONG_EINE_INSEL, 20); + mp3_zugunten = true; + mp3_isused = true; + } + else + mp3_zugunten = false; + } break; case ZU_AT_HOME: szene_time_ms = msecs; @@ -370,23 +392,37 @@ void move_zugunten() break; case ZU_STOPPES_AT_HOME: if(zugunten.fade_off() == false) + zugunten_state = ZU_STOPPED_PLAYING; + break; + case ZU_STOPPED_PLAYING: + if(mp3_zugunten == true) { - zugunten_state = ZU_INIT; - next_move_szene_possible = true; - taster_aussen_move.reset(); - Serial.printf("Zugunten stopped\n"); + if(mp3ply.fade_out() == false && mp3ply.is_playing() == 0) + { + zugunten_state = ZU_DONE; + mp3_isused = false; + } } + else + zugunten_state = ZU_DONE; + break; + case ZU_DONE: + next_move_szene_possible = true; + taster_aussen_move.reset(); + zugunten_state = ZU_INIT; + Serial.printf("Zugunten stopped\n"); break; } } +bool mp3_zugoben = false; unsigned int zugoben_error = 0; const unsigned int ZUGOBEN_MAX_ERROR_COUNT = 5; const unsigned long ZUGOBEN_DRIVES_TO_BRIDGE_MS = 2000; const unsigned long ZUGOBEN_DRIVES_ON_BRIDGE_MS = 2000; const unsigned long ZUGOBEN_MAX_TIME_TO_HOME_MS = 10000; ///timeout time const uint8_t ZUGOBEN_SPEED_ON_BRIDGE = 80; -typedef enum {ZO_INIT = 0, ZO_AT_HOME, ZO_DRIVES_TO_BRIDGE, ZO_DRIVES_SLOWDOWN_ON_BRIDGE, ZO_DRIVES_ON_BRIDGE, ZO_DRIVES_HOME, ZO_STOPPES_AT_HOME} szene_zugoben_t; +typedef enum {ZO_INIT = 0, ZO_AT_HOME, ZO_DRIVES_TO_BRIDGE, ZO_DRIVES_SLOWDOWN_ON_BRIDGE, ZO_DRIVES_ON_BRIDGE, ZO_DRIVES_HOME, ZO_STOPPES_AT_HOME,ZO_STOPPED_PLAYING,ZO_DONE} szene_zugoben_t; szene_zugoben_t zugoben_state = ZO_INIT; void move_zugoben() { @@ -399,7 +435,18 @@ void move_zugoben() if (zugoben_error > ZUGOBEN_MAX_ERROR_COUNT) zugoben_state = ZO_STOPPES_AT_HOME; else + { + if(mp3_isused == false) + { + Serial.printf("Playing Weihnachtsbahn\n"); + mp3ply.play_vol(SONG_WEIHNACHTSBAHN, 20); + mp3_zugoben = true; + mp3_isused = true; + } + else + mp3_zugoben = false; zugoben_state = ZO_AT_HOME; + } break; case ZO_AT_HOME: szene_time_ms = msecs; @@ -441,20 +488,34 @@ void move_zugoben() break; case ZO_STOPPES_AT_HOME: if(zugoben.fade_off() == false) + zugoben_state = ZO_STOPPED_PLAYING; + break; + case ZO_STOPPED_PLAYING: + if(mp3_zugoben == true) { - zugoben_state = ZO_INIT; - next_move_szene_possible = true; - taster_aussen_move.reset(); - Serial.printf("Zugoben stopped at home\n"); + if(mp3ply.fade_out() == false && mp3ply.is_playing() == 0) + { + zugoben_state = ZO_DONE; + mp3_isused = false; + } } + else + zugoben_state = ZO_DONE; + break; + case ZO_DONE: + zugoben_state = ZO_INIT; + next_move_szene_possible = true; + taster_aussen_move.reset(); + Serial.printf("Zugoben stopped at home\n"); break; } } +bool mp3_soben = false; unsigned int soben_error = 0; const unsigned int SOBEN_MAX_ERROR_COUNT = 5; const unsigned long SOBEN_MAX_DRIVES_TIME_MS = 30000; ///timeout time -typedef enum {SO_INIT = 0, SO_AT_HOME, SO_DRIVES_HOME, SO_STOPPES_AT_HOME} szene_soben_t; +typedef enum {SO_INIT = 0, SO_AT_HOME, SO_DRIVES_HOME, SO_STOPPES_AT_HOME,SO_STOPPED_PLAYING, SO_DONE} szene_soben_t; szene_soben_t soben_state = SO_INIT; void move_schiene_oben() { @@ -467,7 +528,18 @@ void move_schiene_oben() if(soben_error > SOBEN_MAX_ERROR_COUNT) soben_state = SO_STOPPES_AT_HOME; else + { + if(mp3_isused == false) + { + Serial.printf("Playing Weihnachtsbäckerei\n"); + mp3ply.play_vol(SONG_WEIHNACHTSBAECKEREI, 20); + mp3_soben = true; + mp3_isused = true; + } + else + mp3_soben = false; soben_state = SO_AT_HOME; + } break; case SO_AT_HOME: szene_time_ms = millis(); @@ -492,6 +564,21 @@ void move_schiene_oben() break; case SO_STOPPES_AT_HOME: relais_wolke_schiene.off(); + soben_state = SO_STOPPED_PLAYING; + break; + case SO_STOPPED_PLAYING: + if(mp3_soben == true) + { + if(mp3ply.fade_out() == false && mp3ply.is_playing() == 0) + { + soben_state = SO_DONE; + mp3_isused = false; + } + } + else + soben_state = SO_DONE; + break; + case SO_DONE: soben_state = SO_INIT; next_move_szene_possible = true; taster_aussen_move.reset(); @@ -500,8 +587,6 @@ void move_schiene_oben() } } - - bool licht_update() { bool fade_updated = false; @@ -541,27 +626,97 @@ bool licht_update() return(fade_updated); } +void disco_licht() +{ + led_sterne1.theaterChaseRainbow(); + led_sterne2.theaterChaseRainbow(); + led_sternbilder1.theaterChaseRainbow(); + led_sternbilder2.theaterChaseRainbow(); + led_sternbilder3.theaterChaseRainbow(); + led_tanne.theaterChaseRainbow(); + led_bauhof.theaterChaseRainbow(); + led_burg.theaterChaseRainbow(); + led_teich.theaterChaseRainbow(); + led_back.theaterChaseRainbow(); + + licht.fade_off(); + relais_spiegel.off(); + rgb_leds.show(); +} + +const unsigned long MAX_DISCO_TIME = 120000; void taster_abfrage() { - if(next_licht_szene_possible == true) + if(next_licht_szene_possible == true && next_move_szene_possible == true && digitalRead(PIN_TASTER_AUSSEN_LICHT) == LOW && digitalRead(PIN_TASTER_AUSSEN_MOVE) == LOW) { - if(taster_aussen_licht.pressed() == true) - { - Serial.printf("Aussenlicht pressed\n"); - licht_szene++; - licht_all_count++; - next_licht_szene_possible = false; - } - } + unsigned long disco_time = millis(); + disco_all_count++; + uint32_t stored_licht_state_flag = licht_state_flag; - if(next_move_szene_possible == true) - { - if(taster_aussen_move.pressed() == true) + uint8_t randSongNumber = random(0, 3); + Serial.printf("Disco! Playing Song %d\n", randSongNumber); + switch(randSongNumber) { - Serial.printf("Move pressed\n"); - move_szene++; - move_all_count++; - next_move_szene_possible = false; + case 0: + mp3ply.play_vol(SONG_DISCO_LASTCHRISTMAS,20); + break; + case 1: + mp3ply.play_vol(SONG_DISCO_DOTHEYKNOWITSCHRISTMAS,20); + break; + case 2: + mp3ply.play_vol(SONG_DISCO_MARYSBOYCHILD,20); + break; + default: + mp3ply.play_vol(SONG_DISCO_LASTCHRISTMAS,20); + break; + } + + while(mp3ply.is_playing() == 0) + { + disco_licht(); + Serial.printf("Waiting until MP3 player starts\n"); + delay(100); + } + while(millis() - disco_time < MAX_DISCO_TIME) + { + disco_licht(); + Serial.printf("Playing Disco!!!\n"); + } + while(mp3ply.fade_out()==true) + {delay(100);} + Serial.printf("Disco done.\n"); + rgb_leds.clear(); + rgb_leds.show(); + licht_state_flag = 0; + licht_update(); + licht_state_flag = stored_licht_state_flag; + while( true == licht_update()) + {delay(1);} + taster_aussen_licht.reset(); + taster_aussen_move.reset(); + } + else + { + if(next_licht_szene_possible == true) + { + if(taster_aussen_licht.pressed() == true) + { + Serial.printf("Aussenlicht pressed\n"); + licht_szene++; + licht_all_count++; + next_licht_szene_possible = false; + } + } + + if(next_move_szene_possible == true) + { + if(taster_aussen_move.pressed() == true) + { + Serial.printf("Move pressed\n"); + move_szene++; + move_all_count++; + next_move_szene_possible = false; + } } } } @@ -580,6 +735,9 @@ void updateNVS() case 2: NVS.setInt("move", move_all_count); break; + case 3: + NVS.setInt("disco",disco_all_count); + break; default: value = 0; } @@ -598,7 +756,8 @@ void show_counters() } moni.clear(); moni.header("Zaehler"); - moni.data(30,12,(uint64_t)licht_all_count, "Licht"); + moni.data(20,12,(uint64_t)licht_all_count, "Licht"); + moni.data(60,12, (uint64_t)disco_all_count, "Disco"); moni.data(100,12, (uint64_t)move_all_count, "Moves"); moni.data(15,38,(uint64_t)zugunten_error, "ZUErr"); moni.data(60,38,(uint64_t)zugoben_error, "ZOErr");