From 95a8645fad77a0db12e1187014f0d15ee26b8fb0 Mon Sep 17 00:00:00 2001 From: bdring Date: Fri, 29 Jun 2018 16:41:19 -0500 Subject: [PATCH] Fixing Neoplixel Version The Neopixel version was not working. I updated to the latest FastLED library that uses the RMT feature and a second core. I also updated the code to make it easier to deal with the differences between the Neopixel and Dotstar versions. --- README.md | 2 - TWANG32/TWANG32.ino | 157 +++++++++++++++++++++++++++++--------------- TWANG32/config.h | 68 +++++++++++++++++++ TWANG32/settings.h | 26 +++----- TWANG32/wifi_ap.h | 10 ++- 5 files changed, 189 insertions(+), 74 deletions(-) create mode 100644 TWANG32/config.h diff --git a/README.md b/README.md index 55f1f66..551dfde 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,6 @@ This was ported from the [TWANG fork](https://github.com/bdring/TWANG) by bdring ## TO DO List: -<<<<<<< HEAD - Wireless features~~ - 2 Player features by linking controllers. TBD ======= @@ -52,7 +51,6 @@ This was ported from the [TWANG fork](https://github.com/bdring/TWANG) by bdring - More robust. - Integrated audio amplifier. - Python (it might be fun to make a Python version) ->>>>>>> origin/master - Digitized Audio - Currently the port uses the same square wave tones of the the Arduino version. diff --git a/TWANG32/TWANG32.ino b/TWANG32/TWANG32.ino index 4cc973c..ac6eeeb 100644 --- a/TWANG32/TWANG32.ino +++ b/TWANG32/TWANG32.ino @@ -9,17 +9,27 @@ It was inspired by Robin Baumgarten's Line Wobbler Game Recent Changes - - JOYSTICK_DEBUG was left on...turned it off - - Web page fields now have type='number' so they bring up a number keyboard - - Refresh the brightness when it changes. - - More Screen Savers - - Better looking reset after gameover - - Better looking restart after boss kill - - Updated readme with video and latest info + - Updated to move FastLEDshow to core 0 + Fixed Neopixel + - Used latest FastLED library..added compile check + - Updated to move FastLEDshow to core 0 + - Reduced MAX_LEDS on Neopixel + - Move some defines to a separate config.h file to make them accessible to other files + - Changed volume typo on serial port settings menu + Project TODO + - Make the strip type configurable via serial and wifi + + + Usage Notes: + - Changes to LED strip and other hardware are in config.h + - Change the strip type to what you are using and compile/load firmware + - Use Serial port or Wifi to set your strip length. */ -#define VERSION "2018-03-31" +// + +#define VERSION "2018-06-28" #include #include @@ -27,6 +37,7 @@ #include "RunningMedian.h" // twang files +#include "config.h" #include "twang_mpu.h" #include "Enemy.h" #include "Particle.h" @@ -39,33 +50,13 @@ #include "settings.h" #include "wifi_ap.h" - -#define DATA_PIN 16 -#define CLOCK_PIN 17 - -#define VIRTUAL_LED_COUNT 1000 - -// what type of LED Strip....uncomment only one -#define USE_APA102 -//#define USE_NEOPIXEL - -#ifdef USE_APA102 - #define LED_TYPE APA102 - #define LED_COLOR_ORDER BGR // typically this will be the order, but switch it if not - #define CONVEYOR_BRIGHTNES 8 - #define LAVA_OFF_BRIGHTNESS 4 -#endif - -#ifdef USE_NEOPIXEL - #define CONVEYOR_BRIGHTNES 40 // low neopixel values are nearly off, they need a higher value - #define LAVA_OFF_BRIGHTNESS 15 +#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000) + #error "Requires FastLED 3.1 or later; check github for latest code." #endif -//#define BRIGHTNESS 150 #define DIRECTION 1 -#define MIN_REDRAW_INTERVAL 16 // Min redraw interval (ms) 33 = 30fps / 16 = 63fps #define USE_GRAVITY 0 // 0/1 use gravity (LED strip going up wall) #define BEND_POINT 550 // 0/1000 point at which the LED strip goes up the wall @@ -75,8 +66,6 @@ int levelNumber = 0; #define TIMEOUT 20000 // time until screen saver in milliseconds - - int joystickTilt = 0; // Stores the angle of the joystick int joystickWobble = 0; // Stores the max amount of acceleration (wobble) @@ -85,7 +74,7 @@ int joystickWobble = 0; // Stores the max amount of acceleration (wob int attack_width = DEFAULT_ATTACK_WIDTH; #define ATTACK_DURATION 500 // Duration of a wobble attack (ms) long attackMillis = 0; // Time the attack started -bool attacking = 0; // Is the attack in progress? +bool attacking = 0; // Is the attack in progress? #define BOSS_WIDTH 40 // TODO all animation durations should be defined rather than literals @@ -161,33 +150,90 @@ bool lastLevel = false; int score = 0; +#define FASTLED_SHOW_CORE 0 // -- The core to run FastLED.show() + +// -- Task handles for use in the notifications +static TaskHandle_t FastLEDshowTaskHandle = 0; +static TaskHandle_t userTaskHandle = 0; + +/** show() for ESP32 + * Call this function instead of FastLED.show(). It signals core 0 to issue a show, + * then waits for a notification that it is done. + */ +void FastLEDshowESP32() +{ + if (userTaskHandle == 0) { + // -- Store the handle of the current task, so that the show task can + // notify it when it's done + userTaskHandle = xTaskGetCurrentTaskHandle(); + + // -- Trigger the show task + xTaskNotifyGive(FastLEDshowTaskHandle); + + // -- Wait to be notified that it's done + const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 200 ); + ulTaskNotifyTake(pdTRUE, xMaxBlockTime); + userTaskHandle = 0; + } +} + +/** show Task + * This function runs on core 0 and just waits for requests to call FastLED.show() + */ +void FastLEDshowTask(void *pvParameters) +{ + // -- Run forever... + for(;;) { + // -- Wait for the trigger + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + + // -- Do the show (synchronously) + FastLED.show(); + + // -- Notify the calling task + xTaskNotifyGive(userTaskHandle); + } +} + void setup() { Serial.begin(115200); - Serial.print("\r\nTWANG32 VERSION: "); Serial.println(VERSION); + Serial.print("\r\nTWANG32 VERSION: "); Serial.println(VERSION); - settings_init(); + settings_init(); // load the user settings from EEPROM Wire.begin(); accelgyro.initialize(); + +#ifdef USE_NEOPIXEL + Serial.print("\r\nCompiled for WS2812B (Neopixel) LEDs"); + FastLED.addLeds(leds, MAX_LEDS); +#endif - FastLED.addLeds(leds, VIRTUAL_LED_COUNT); +#ifdef USE_APA102 + Serial.print("\r\nCompiled for APA102 (Dotstar) LEDs"); + FastLED.addLeds(leds, MAX_LEDS); +#endif + FastLED.setBrightness(user_settings.led_brightness); FastLED.setDither(1); + + // -- Create the ESP32 FastLED show task + xTaskCreatePinnedToCore(FastLEDshowTask, "FastLEDshowTask", 2048, NULL, 2, &FastLEDshowTaskHandle, FASTLED_SHOW_CORE); sound_init(DAC_AUDIO_PIN); - ap_setup(); + ap_setup(); stage = STARTUP; stageStartTime = millis(); lives = user_settings.lives_per_level; + } void loop() { long mm = millis(); - int brightness = 0; - + int brightness = 0; ap_client_check(); // check for web client checkSerialInput(); @@ -206,6 +252,8 @@ void loop() { if (mm - previousMillis >= MIN_REDRAW_INTERVAL) { getInput(); + + long frameTimer = mm; previousMillis = mm; @@ -218,11 +266,13 @@ void loop() { stage = WIN; } }else{ - if(lastInputTime+TIMEOUT < mm){ - + if(lastInputTime+TIMEOUT < mm){ stage = SCREENSAVER; } } + + + if(stage == SCREENSAVER){ screenSaverTick(); }else if(stage == STARTUP){ @@ -249,7 +299,8 @@ void loop() { playerPosition += playerPositionModifier; if(!attacking){ SFXtilt(joystickTilt); - int moveAmount = (joystickTilt/6.0); + //int moveAmount = (joystickTilt/6.0); // 6.0 is ideal at 16ms interval (6.0 / (16.0 / MIN_REDRAW_INTERVAL)) + int moveAmount = (joystickTilt/(6.0)); // 6.0 is ideal at 16ms interval if(DIRECTION) moveAmount = -moveAmount; moveAmount = constrain(moveAmount, -MAX_PLAYER_SPEED, MAX_PLAYER_SPEED); @@ -310,9 +361,10 @@ void loop() { lives = user_settings.lives_per_level; } - } + } - FastLED.show(); + //FastLED.show(); + FastLEDshowESP32(); } @@ -658,8 +710,6 @@ void tickStartup(long mm) } - - void tickEnemies(){ for(int i = 0; i 3) - //sound(380 + random8(200), MAX_VOLUME / 2); // scary lava noise + leds[p] = CRGB(180, 100, 0); + } } } lavaPool[i] = LP; @@ -824,7 +873,7 @@ void tickConveyors(){ if(speed < 0) n = (led + (m/100)) % levels; - b = map(n, 5, 0, 0, CONVEYOR_BRIGHTNES); + b = map(n, 5, 0, 0, CONVEYOR_BRIGHTNESS); if(b > 0) leds[led] = CRGB(0, 0, b); } diff --git a/TWANG32/config.h b/TWANG32/config.h new file mode 100644 index 0000000..7fa8a69 --- /dev/null +++ b/TWANG32/config.h @@ -0,0 +1,68 @@ +/* + TWANG32 - An ESP32 port of TWANG + (c) B. Dring 3/2018 + License: Creative Commons 4.0 Attribution - Share Alike + + TWANG was originally created by Critters + https://github.com/Critters/TWANG + + Basic hardware definitions + + Light Strip Notes: + + Noepixel / WS2812 + - Low Cost + - You might already have a strip. + - No Clock Line - This means a fixed and relatively slow data rate and only shorter strips can be used + - Poor Dynamic Range - The low end of brightness is basically not visible + Dotstar (Highly recommended) + - Higher Cost + - Higher speed - Longer strips can be used. + - Great dynamic range, so lower levels and more colors can be used. + + +*/ + +#ifndef CONFIG_H + #define CONFIG_H + +#define DATA_PIN 16 +#define CLOCK_PIN 17 + +/* Game is rendered to this and scaled down to your strip. + This allows level definitions to work on all strip lengths */ +#define VIRTUAL_LED_COUNT 1000 + +// what type of LED Strip....uncomment to define only one of these +#define USE_APA102 +//#define USE_NEOPIXEL + +// Check to make sure LED choice was done right +#if !defined(USE_NEOPIXEL) && !defined(USE_APA102) + #error "You must have USE_APA102 or USE_NEOPIXEL defined in config.h" +#endif + +#if defined(USE_NEOPIXEL) && defined(USE_APA102) + #error "Both USE_APA102 and USE_NEOPIXEL are defined in config.h. Only one can be used" +#endif + +#ifdef USE_APA102 + #define LED_TYPE APA102 + #define LED_COLOR_ORDER BGR // typically this will be the order, but switch it if not + #define CONVEYOR_BRIGHTNESS 8 + #define LAVA_OFF_BRIGHTNESS 4 + #define MAX_LEDS VIRTUAL_LED_COUNT // these LEDS can handle the max + #define MIN_REDRAW_INTERVAL 1000.0 / 60.0 // divide by frames per second..if you tweak adjust player speed +#endif + +#ifdef USE_NEOPIXEL + #define LED_TYPE NEOPIXEL + #define CONVEYOR_BRIGHTNESS 40 // low neopixel values are nearly off, Neopixels need a higher value + #define LAVA_OFF_BRIGHTNESS 15 // low neopixel values are nearly off, Neopixels need a higher value + #define MAX_LEDS 288 // Neopixels cannot handle the framerate + #define MIN_REDRAW_INTERVAL 1000.0 / 60.0 // divide by frames per second..if you tweak adjust player speed +#endif + + + +#endif \ No newline at end of file diff --git a/TWANG32/settings.h b/TWANG32/settings.h index f02eb24..d0661ef 100644 --- a/TWANG32/settings.h +++ b/TWANG32/settings.h @@ -14,7 +14,7 @@ // LEDS #define NUM_LEDS 144 #define MIN_LEDS 60 -#define MAX_LEDS 1000 + #define DEFAULT_BRIGHTNESS 150 @@ -40,13 +40,10 @@ const uint8_t LIVES_PER_LEVEL = 3; // default lives per level #define MAX_JOYSTICK_DEADZONE 12 // AUDIO -#define DEFAULT_VOLUME 180 // 0 to 255 +#define DEFAULT_VOLUME 20 // 0 to 255 #define MIN_VOLUME 0 #define MAX_VOLUME 255 - - - #define DAC_AUDIO_PIN 25 // should be 25 or 26 only enum ErrorNums{ @@ -122,6 +119,7 @@ void processSerial(char inChar) switch(readBuffer[readIndex]){ case '?': readIndex = 0; + show_game_stats(); show_settings_menu(); return; break; @@ -295,7 +293,10 @@ void show_settings_menu() { Serial.print("\r\nC="); Serial.print(user_settings.led_count); - Serial.println(" (LED Count 100-1000..forces restart)"); + + Serial.print(" (LED Count 60-"); + Serial.print(MAX_LEDS); + Serial.println(")"); Serial.print("B="); Serial.print(user_settings.led_brightness); @@ -303,7 +304,7 @@ void show_settings_menu() { Serial.print("S="); Serial.print(user_settings.audio_volume); - Serial.println(" (Sound Volume 0-10)"); + Serial.println(" (Sound Volume 0-255)"); Serial.print("D="); Serial.print(user_settings.joystick_deadzone); @@ -325,7 +326,7 @@ void show_settings_menu() { void show_game_stats() { - Serial.println("\r\n ===== Play statistics ======"); + Serial.println("\r\n===== Play statistics ======"); Serial.print("Games played: ");Serial.println(user_settings.games_played); if (user_settings.games_played > 0) { Serial.print("Average Score: ");Serial.println(user_settings.total_points / user_settings.games_played); @@ -367,16 +368,10 @@ void settings_eeprom_read() { void settings_eeprom_write() { - Serial.println("Settings write..."); - sound_pause(); // prevent interrupt from causing crash - - EEPROM.begin(EEPROM_SIZE); - Serial.println("EEPROM open for write..."); - uint8_t temp[sizeof(user_settings)]; memcpy(temp, (uint8_t*)&user_settings, sizeof(user_settings)); @@ -385,8 +380,7 @@ void settings_eeprom_write() { EEPROM.write(i, temp[i]); } - EEPROM.commit(); - + EEPROM.commit(); EEPROM.end(); sound_resume(); // restore sound interrupt diff --git a/TWANG32/wifi_ap.h b/TWANG32/wifi_ap.h index 11c92dd..d880693 100644 --- a/TWANG32/wifi_ap.h +++ b/TWANG32/wifi_ap.h @@ -54,9 +54,15 @@ void sendStatsPage(WiFiClient client) { client.print(""); - client.print(""); + client.print ("' min='60' max='"); + client.print (MAX_LEDS); + client.print ("'>"); client.print("
LED Count (60-1000)
Brightness (10-255)