/*
   程序:  Direct Task Notification 邮箱功能
   要点:
      如此复杂的电灯程序,只是大家演示一下
      巧用任务的通知Value当作邮箱功能
      
      如何将4个uint8_t的数据打包成uint32_t,
      然后通过任务通知传递过去,
      并且在目的地进行拆解的方法。

      写完整个程序,感觉和走私,偷渡一样
      
   公众号:孤独的二进制
*/
#include <Adafruit_NeoPixel.h>
#define NEOPIN 33
#define NUMPIXELS 16

#define RPIN 34
#define GPIN 35
#define BPIN 32
#define SPIN 36 // speed

static TaskHandle_t xTaskNeoRing = NULL;

void configTask(void *pvParam) {
  pinMode(RPIN, INPUT);
  pinMode(GPIN, INPUT);
  pinMode(BPIN, INPUT);
  pinMode(SPIN, INPUT);
  uint8_t r_value = 0;
  uint8_t g_value = 0;
  uint8_t b_value = 0;
  uint8_t s_value = 100;

  while (1) {
    r_value = map(analogRead(RPIN), 0, 4095, 0, 255);
    g_value = map(analogRead(GPIN), 0, 4095, 0, 255);
    b_value = map(analogRead(BPIN), 0, 4095, 0, 255);
    s_value = map(analogRead(SPIN), 0, 4095, 10, 200);

    uint32_t rgb = s_value << 24 | r_value << 16 | g_value << 8 | b_value << 0;

    xTaskNotify(xTaskNeoRing, rgb, eSetValueWithOverwrite);

    vTaskDelay(100);
  }
}

void neoRing(void *pvParam) {

  Adafruit_NeoPixel pixels(NUMPIXELS, NEOPIN, NEO_GRB + NEO_KHZ800);
  pixels.begin();

  uint32_t srgb = 0;
  uint8_t r = 0;
  uint8_t g = 0;
  uint8_t b = 0;
  uint8_t s = 100;

  while (1) {

    pixels.clear();
    for (int i = 0; i < NUMPIXELS; i++) {

      xTaskNotifyWait(0x00, 0x00, &srgb, 0);
      s = (srgb & 0xff000000) >> 24;
      r = (srgb & 0x00ff0000) >> 16;
      g = (srgb & 0x0000ff00) >> 8;
      b = (srgb & 0x000000ff) >> 0;

      pixels.setPixelColor(i, pixels.Color(r, g, b));
      pixels.show();
      vTaskDelay(s * 5);
    }
  }
}

void setup() {
  Serial.begin(115200);

  xTaskCreate(configTask, "Configuration", 1024 * 10, NULL, 1, NULL);
  xTaskCreate(neoRing, "Neo Ring", 1024 * 20, NULL, 1, &xTaskNeoRing);

  vTaskDelete(NULL); //没我啥事了,自宫ba
}


void loop() {
}