Skip to content

Instantly share code, notes, and snippets.

@hpwit
Last active June 18, 2020 12:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hpwit/2fff5288c8abd535056a1c22536c6a9a to your computer and use it in GitHub Desktop.
Save hpwit/2fff5288c8abd535056a1c22536c6a9a to your computer and use it in GitHub Desktop.
#include <WiFi.h>
//#include <ESP8266WiFi.h>
#include "SD.h"
#include "SPI.h"
//#include "FS.h"
#include <Wire.h>
//#include <LiquidCrystal_I2C.h>
//LiquidCrystal_I2C lcd(0x27, 16, 2);
#include "esp_task_wdt.h"
#include <WiFiClient.h>
#include <Artnet.h>
WiFiServer server(80);
#define FASTLED_ESP32_I2S true
#include "FastLED.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
FASTLED_USING_NAMESPACE
#define FASTLED_SHOW_CORE 0
#define NB_STRIPS 4 //4
#define NB_LEDS_PER_STRIP 462 //462
#define NUM_LEDS NB_STRIPS * NB_LEDS_PER_STRIP
#define UNIVERSE_SIZE 170
uint8_t allframe[4+NUM_LEDS*3];
CRGB *leds;
#include "freertos/queue.h"
static uint8_t frame[NUM_LEDS*3];
uint8_t readbuffer[NUM_LEDS*3];
Artnet artnet;
const char* ssid = "DRINK_UP";
const char* password = "15041988";
#define JINX_CORE 0
#define SD_CORE 0
static TaskHandle_t FastLEDshowTaskHandle2 = 0;
static TaskHandle_t FastLEDshowTaskHandle3 = 0;
static TaskHandle_t userTaskHandle = 0;
static TaskHandle_t checkWifiTaskHandle;
static TaskHandle_t userTaskHandle2 = 0;
static uint32_t deb=0;
static uint32_t fin=0;;
volatile bool debounceToggle=false;
const byte PIN1 = 2; //23;//2 ;
const byte PIN2 = 25 ;
const byte PIN3 = 33 ;
const byte PIN4 = 32 ;
const byte PIN_NEXT = 26;//27;//5;//27 ;
const byte PIN_PREV = 27 ;
const byte PIN_RECORD = 4;//12 ;//19;//12 ;
const byte PIN_TOGGLE_JINX_SD =13;// 21;//13 ;
volatile bool record_status=false;
volatile bool isJinx=true; //this will command the fact tha we do start by jinx.
char READ_NAME[]="file";
File root;
File myFile;
static uint32_t nbframes=0;
char SAVE_NAME[]="file";
volatile bool new_record=false;
volatile int recordingnumber=0;
volatile bool stopped=false;
volatile bool nextfile=false;
volatile bool prevfile=false;
volatile bool switch_disp_mode=true;
volatile bool switch_record_mode=false;
volatile bool sd_card_present=false;
#define FILE_SIZE 100
#define MAX_FILE 200
char filenames[MAX_FILE * FILE_SIZE];
char filename[FILE_SIZE];
volatile int currentfile=0;
SemaphoreHandle_t xSemaphore = NULL;
void checkWifi()
{
if (userTaskHandle2 == 0) {
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 200 );
userTaskHandle2 = xTaskGetCurrentTaskHandle();
xTaskNotifyGive(checkWifiTaskHandle);
//to thge contrary to the other one we do not wait for the display task to come back
}
}
static uint32_t framelost=0;
static uint32_t decal_lost=0;
static uint32_t framelost_total=0;
static uint32_t delay_frame=0;
static uint32_t esptime=0;
static bool first_frame=false;
static bool first_frame_record=false;
static uint32_t time_now_record=0;
static uint32_t frameread=0;
static uint32_t frameread2=0;
static bool oktorecord=false;
static uint32_t record_duration=0;
void checkWifiTask(void *pvParameters)
{
xSemaphore = xSemaphoreCreateMutex();
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 500 );
artnet.nbframeread=0;
artnet.frameslues=0;
Serial.println("ready to record");
// -- Run forever...
for(;;) {
// ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
//vTaskDelay(1 );
//xSemaphoreTake( xSemaphore, portMAX_DELAY);
//esp_task_wdt_reset();
while( (!new_record) && record_status && isJinx )
{
//Serial.println("ee");
//vTaskDelay(1 );
//esp_task_wdt_reset();
/* TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
TIMERG0.wdt_feed=1; // feed dog
TIMERG0.wdt_wprotect=0; // write protect
// feed dog 1
TIMERG1.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
TIMERG1.wdt_feed=1; // feed dog
TIMERG1.wdt_wprotect=0; // write protect*/
if(artnet.nbframeread<artnet.frameslues)
{
// fin=millis();
//time_now_record=__clock_cycles();// ESP.getCycleCount();
if(!first_frame_record)
{
first_frame_record=true;
// delay_frame=time_now_record;
//framelost=time_now_record;
frameread=0;
record_duration=millis();
//decal_lost=0;
Serial.println("frist frame record");
//Serial.println(record_duration);
//esp_task_wdt_reset();
}
//decal_lost=(time_now_record-framelost)/240;
//framelost=time_now_record;
//decal_lost=artnet.getElaspseTime();
//myFile.write((uint8_t*)&decal_lost,4);
artnet.getframe3((uint8_t*) allframe);
myFile.write((uint8_t *)allframe,NUM_LEDS*sizeof(CRGB)+4);
frameread++;
if(frameread%200==0)
{
Serial.printf("frames read:%d frames read2:%d Frameslues: %d artnet frameread:%d lost frames:%d\n",frameread,frameread2,artnet.frameslues,artnet.nbframeread,artnet.lostframes);
}
//deb=deb+millis()-fin;
//FastLED.show();
//if(!record_status)
//oktorecord=false;
}
record_status=digitalRead(PIN_RECORD);
TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE; // write enable
TIMERG0.wdt_feed=1; // feed dog
TIMERG0.wdt_wprotect=0; // write protect
}
if(artnet.nbframeread>1)
{
uint32_t g=millis();
Serial.printf("%d %d\n",g,record_duration);
record_duration=g-record_duration;
vTaskDelete(NULL);
}
//Serial.printf("%d
}
}
void selectPrevFile()
{
Serial.printf("Opening Prev File");
if(recordingnumber==0)
{
Serial.println("no file\n");
return;
}
Serial.printf("current file :%d total%d\n", currentfile,recordingnumber);
if(currentfile==0)
currentfile=recordingnumber-1;
else
currentfile--;
char fi[FILE_SIZE];
memset(fi,0,FILE_SIZE);
sprintf(fi,"%s",&filenames[currentfile*FILE_SIZE]);
myFile=SD.open(fi);
Serial.printf("Opening file %s\n",myFile.name());
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("Playing");
//lcd.setCursor(0, 1);
//lcd.print(myFile.name());
}
void selectNextFile()
{
if(!sd_card_present)
{
Serial.println("No card mounted");
return;
}
Serial.println("looking for next file");
if(recordingnumber==0)
{
Serial.println("no file\n");
return;
}
Serial.printf("current file number:%d\n",currentfile);
currentfile=(currentfile+1)%recordingnumber;
Serial.printf("new file number:%d\n",currentfile);
char fi[FILE_SIZE];
memset(fi,0,FILE_SIZE);
sprintf(fi,"%s",&filenames[currentfile*FILE_SIZE]);
Serial.printf("try to open file %s %s\n",fi, &filenames[currentfile*FILE_SIZE]);
myFile=SD.open(fi);
Serial.printf("Opening file %s\n",myFile.name());
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("Playing");
//lcd.setCursor(0, 1);
//lcd.print(myFile.name());
return;
int rewind_number=0;
if(myFile)
myFile.close();
myFile = root.openNextFile();
if(!myFile)
{
root.rewindDirectory();
myFile = root.openNextFile();
if(!myFile)
{
Serial.println("No file on the card2");
return;
}
}
while(myFile.isDirectory() )
{
myFile = root.openNextFile();
if(!myFile)
{
if(rewind_number==1)
{
Serial.println("No file on the card1");
return;
}
root.rewindDirectory();
myFile = root.openNextFile();
rewind_number=1;
}
}
Serial.printf("Opening file %s\n",myFile.name());
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("Playing");
//lcd.setCursor(0, 1);
//lcd.print(myFile.name());
}
void openNextFileForRecording()
{
if(myFile)
myFile.close();
int recordnum=0;
if(recordingnumber>0)
recordnum=recordingnumber-1;
else
recordnum=recordingnumber;
if(!sd_card_present)
{
Serial.println("No card mounted");
return;
}
memset(filename, 0, FILE_SIZE);
sprintf(filename,"/%s_%03d.dat",SAVE_NAME,recordnum);
myFile = SD.open(filename); //, FILE_WRITE);
while(myFile)
{
myFile.close();
recordnum++;
memset(filename, 0, FILE_SIZE);
sprintf(filename,"/%s_%03d.dat",SAVE_NAME,recordnum);
myFile = SD.open(filename); //, FILE_WRITE);
}
recordingnumber++;
sprintf(&filenames[(recordingnumber-1)*FILE_SIZE],"%s",filename);
Serial.printf("Opening file :%s for recording position %d\n",filename,recordingnumber-1);
myFile = SD.open(filename, FILE_WRITE);
if(!myFile)
{
Serial.printf("Unable to open %s for writing\n",filename);
}
}
void numberfiles()
{
memset(filenames,0,MAX_FILE * FILE_SIZE);
recordingnumber=0;
root=SD.open("/");
myFile = root.openNextFile();
while(myFile)
{
if(!myFile.isDirectory())
{
sprintf(&filenames[recordingnumber*FILE_SIZE],"%s",myFile.name());
myFile.close();
recordingnumber++;
}
myFile = root.openNextFile();
}
//recordingnumber++;
if(recordingnumber>0)
{
char fi[FILE_SIZE];
memset(fi,0,FILE_SIZE);
sprintf(fi,"%s",&filenames[0]);
myFile=SD.open(fi);
Serial.printf("Opening file %s\n",myFile.name());
currentfile=0;
root.rewindDirectory();
Serial.printf("Number of files already stored:%d\n",recordingnumber);
}
else
{
Serial.println("No file stored");
}
}
void FastLEDshowESP322()
{
if (userTaskHandle == 0) {
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 200 );
userTaskHandle = xTaskGetCurrentTaskHandle();
xTaskNotifyGive(FastLEDshowTaskHandle3);
}
}
void FastLEDshowTask3(void *pvParameters)
{
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 500 );
// -- Run forever...
for(;;) {
// -- Wait for the trigger
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
//if( userTaskHandle==0)
// {
userTaskHandle = xTaskGetCurrentTaskHandle();
if(!first_frame)
{
first_frame=true;
delay_frame=millis();
framelost=delay_frame;
Serial.println("frist frame");
frameread=0;
}
frameread++;
if(frameread%10000==0)
{
decal_lost=millis()-framelost;
framelost=millis();
framelost_total=framelost-delay_frame;
Serial.printf("frameread:%d framecalled:%d\n",frameread,nbframes);
framelost=millis();
}
// artnet.getframe2((uint8_t*) leds);
//memcpy(leds,artnet.getframe(),NUM_LEDS*sizeof(CRGB));
FastLED.show();
userTaskHandle=0; //so we can't have two display tasks at the same time
// }
}
}
void FastLEDshowTask2(void *pvParameters)
{
const TickType_t xMaxBlockTime = pdMS_TO_TICKS( 500 );
// -- Run forever...
for(;;) {
// -- Wait for the trigger
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
if(!first_frame)
{
first_frame=true;
delay_frame=millis();
framelost=delay_frame;
Serial.println("frist frame");
frameread=0;
}
frameread++;
if(artnet.frameslues%100==0)
{
decal_lost=millis()-framelost;
framelost=millis();
framelost_total=framelost-delay_frame;
Serial.printf("frame %ld called frame:%d lost in display:%d lost in arnet:%ld totallost:%f time_total:%d fps_total:%f time:%d fps:%f \n",artnet.frameslues,frameread2,frameread2-frameread,artnet.lostframes,(float)100*artnet.lostframes/artnet.frameslues,framelost_total,(float)artnet.frameslues*1000/(framelost_total),decal_lost,(float)100000/decal_lost);
framelost=millis();
}
artnet.getframe3((uint8_t*) allframe);
//memcpy(leds,artnet.getframe(),NUM_LEDS*sizeof(CRGB));
FastLED.show();
userTaskHandle=0; //so we can't have two display tasks at the same time
}
}
void IRAM_ATTR ISR_Next() {
if(debounceToggle || nextfile)
return;
debounceToggle=true;
nextfile=true;
debounceToggle=false;
}
void IRAM_ATTR ISR_Prev() {
if(debounceToggle || prevfile)
return;
debounceToggle=true;
prevfile=true;
debounceToggle=false;
}
void IRAM_ATTR ISR_Toggle() {
if(debounceToggle || switch_disp_mode)
return;
debounceToggle=true;
// isJinx= digitalRead(PIN_TOGGLE_JINX_SD)==0 ? true:false;
isJinx=!isJinx;
switch_disp_mode=true;
//delay(1000);
debounceToggle=false;
}
/* to uncomment if the code above is not working
void IRAM_ATTR ISR_Toggle() {
if(debounceToggle)
return;
debounceToggle=true;
isJinx= digitalRead(PIN_TOGGLE_JINX_SD)==0 ? true:false;
switch_disp_mode=true;
delay(1000);
debounceToggle=false;
}
*/
void setup() {
Serial.begin(115200);
leds=(CRGB*) (allframe+4);
//lcd.begin(21,22);
//lcd.backlight();
//lcd.setCursor(4, 0);
//lcd.print("DRINK UP");
//create the Interrupt services for the button
pinMode(PIN_NEXT, INPUT_PULLDOWN);
pinMode(PIN_PREV, INPUT_PULLDOWN);
pinMode(PIN_RECORD, INPUT_PULLDOWN);
pinMode(PIN_TOGGLE_JINX_SD,INPUT_PULLDOWN);
attachInterrupt(PIN_NEXT, ISR_Next, RISING);
attachInterrupt(PIN_PREV, ISR_Prev, RISING);
attachInterrupt(PIN_TOGGLE_JINX_SD, ISR_Toggle, CHANGE);
xTaskCreatePinnedToCore(FastLEDshowTask2, "FastLEDshowTask2", 3000, NULL,1, &FastLEDshowTaskHandle2, FASTLED_SHOW_CORE);
// xTaskCreatePinnedToCore(FastLEDshowTask3, "FastLEDshowTas33", 3000, NULL,1, &FastLEDshowTaskHandle3, FASTLED_SHOW_CORE);
// xTaskCreatePinnedToCore(checkWifiTask, "checkWifiTask", 3000, NULL,3, &checkWifiTaskHandle, FASTLED_SHOW_CORE);
SPI.begin(18,19,23,5);
//SPI.begin(14,2,15,13);
//SPI.begin();
if(!SD.begin(5,SPI,80000000)){
Serial.println("Card Mount Failed");
sd_card_present=false;
}
else
{
uint8_t cardType = SD.cardType();
if(cardType == CARD_NONE){
Serial.println("No SD card attached");
sd_card_present=false;
}
else
{
sd_card_present=true;
//root=SD.open("/");
numberfiles();
//selectNextFile();
}
}
//isJinx= digitalRead(PIN_TOGGLE_JINX_SD)==0 ? true:false; //modifié
record_status= digitalRead(PIN_RECORD)==1 ? true:false;
//record_status=1;
bool result=WiFi.softAP(ssid, password, 10, 0, 2);
if(result)
Serial.println("Setting SoftAP ok");
else
Serial.println("Setting SoftAP falied");
IPAddress myIP = WiFi.softAPIP();
Serial.println(WiFi.softAPIP());
delay(2000);
//lcd.clear();
server.begin();
Serial.println("Server started");
// put your setup code here, to run once:
FastLED.addLeds<WS2812, PIN1, GRB>(leds, 0, NB_LEDS_PER_STRIP);
FastLED.addLeds<WS2812, PIN2, GRB>(leds, NB_LEDS_PER_STRIP, NB_LEDS_PER_STRIP);
FastLED.addLeds<WS2812, PIN3, GRB>(leds, NB_LEDS_PER_STRIP*2, NB_LEDS_PER_STRIP);
FastLED.addLeds<WS2812, PIN4, GRB>(leds, NB_LEDS_PER_STRIP*3, NB_LEDS_PER_STRIP);
FastLED.show();
artnet.begin(NUM_LEDS,UNIVERSE_SIZE);
myFile=SD.open("/file_069.dat");
//isJinx=false;
//switch_disp_mode=true;
//checkWifi();
}
uint32_t waitnewtframe=0;
uint32_t timenow=0;
uint32_t diff=0;
uint32_t time_now=0;
uint32_t record_duration2=0;
uint32_t totalrecord=0;
uint32_t shortframes=0;
void loop() {
if(!isJinx )
{
if(switch_disp_mode)
{
Serial.println("SD-Card");
switch_disp_mode=false;
//lcd.clear();
//lcd.setCursor(12, 0);
//lcd.print("MODE");
//lcd.setCursor(12, 1);
//lcd.print("SD");
timenow=ESP.getCycleCount();
record_duration2=millis();
nbframes=0;
totalrecord=0;
shortframes=0;
first_frame=false;
}
if(!myFile)
{
Serial.println("no file open ... looking for net file");
//root=SD.open("/");
selectNextFile();
}
while (myFile.available()>0 and !isJinx)
{
myFile.read((uint8_t*)allframe,NUM_LEDS*sizeof(CRGB)+4);//NUM_LEDS*sizeof(CRGB));
waitnewtframe=*((uint32_t*)allframe);
//myFile.read((uint8_t*)&waitnewtframe,4);
//myFile.read((uint8_t*)leds,NUM_LEDS*sizeof(CRGB));//NUM_LEDS*sizeof(CRGB));
totalrecord=totalrecord+(waitnewtframe/240);
time_now=ESP.getCycleCount();
nbframes++;
diff=(time_now-timenow);
/*
while(diff+50*240<waitnewtframe)
{
time_now=ESP.getCycleCount();
diff=(time_now-timenow);
}*/
// Serial.printf("frame %d\n",nbframes);
if(waitnewtframe>diff)
delayMicroseconds((waitnewtframe-diff)/240);
//Serial.println("ee");
else
shortframes++;
timenow=ESP.getCycleCount();//__clock_cycles();
// memcpy(leds,readbuffer,NUM_LEDS*sizeof(CRGB));
// FastLEDshowESP322();
// xTaskNotifyGive(FastLEDshowTaskHandle3);
// if(nbframes%10000==0)
// Serial.printf("frames %d \n",nbframes);
FastLED.show();
//timenow=__clock_cycles();
//delay(20);
}
//else
//{
record_duration2=millis()-record_duration2;
myFile.seek(0);
Serial.printf("duration %ld nb frzmes:%d total:%d shortframes:%d\n",record_duration2, nbframes,totalrecord/1000,shortframes);
totalrecord=0;
record_duration2=millis();
timenow=__clock_cycles();
nbframes=0;
shortframes=0;
frameread=0;
//}
if(nextfile && !isJinx)
{
selectNextFile();
delay(500);
nextfile=false;
}
if(prevfile && !isJinx)
{
selectPrevFile();
delay(500);
prevfile=false;
}
}
else
{
if( switch_disp_mode)
{
//first_frame=false;
Serial.println("From Jinx");
//lcd.clear();
//lcd.setCursor(12, 0);
//lcd.print("MODE");
//lcd.setCursor(11, 1);
//lcd.print("JINX!");
artnet.frameslues=0;
artnet.lostframes=0;
framelost=0;
decal_lost=0;
framelost_total=0;
delay_frame=0;
first_frame=false;
artnet.resetsync();
switch_disp_mode=false;
frameread2=0;
}
record_status=digitalRead(PIN_RECORD);
//record_status=1;
if(!record_status)
{
if(artnet.read2()==1)
{
//memcpy(leds,artnet.getframe(),NUM_LEDS*sizeof(CRGB));
//FastLED.show();
frameread2++;
xTaskNotifyGive(FastLEDshowTaskHandle2);
//xTaskNotifyGive(checkWifiTaskHandle);
// FastLEDshowESP322();
// artnet.resetsync();
}
}
else
{
//Serial.println("er");
//Serial.printf(switch_record_mode);
if(record_status && switch_record_mode==false)
{
new_record=true;
stopped=false;
switch_record_mode=true;
framelost=0;
decal_lost=0;
framelost_total=0;
delay_frame=0;
first_frame_record=false;
switch_record_mode=false;
artnet.nbframeread=0;
artnet.frameslues=0;
artnet.lostframes=0;
//artnet.currentframenumber=0;
xTaskCreatePinnedToCore(checkWifiTask, "checkWifiTask", 3000, NULL,3, &checkWifiTaskHandle, FASTLED_SHOW_CORE);
if(myFile)
myFile.close();
openNextFileForRecording(); //this will avoid to override existing files
new_record=false;
Serial.println("start new recording");
frameread2=1;
//first_frame=false
}
while(record_status){
// Serial.println("ee");
/* if(new_record)
{
framelost=0;
decal_lost=0;
framelost_total=0;
delay_frame=0;
first_frame_record=false;
switch_record_mode=false;
artnet.nbframeread=0;
artnet.frameslues=0;
artnet.lostframes=0;
if(myFile)
myFile.close();
openNextFileForRecording(); //this will avoid to override existing files
new_record=false;
Serial.println("start new recording");
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("REC...");
//lcd.setCursor(0, 1);
//lcd.print(filename);
}*/
//if(!new_record)
//else
//{
artnet.read2();
// if(artnet.read2()==1)
// {
// xSemaphoreGive( xSemaphore );
// }
//if(artnet.frameslues==1)
// framelost=__clock_cycles();
/*time_now_record=__clock_cycles();
decal_lost=(time_now_record-framelost)/240;
framelost=time_now_record;
oktorecord=true;*/
// }
// {
// frameread2++;
// xTaskNotifyGive(checkWifiTaskHandle);
// }
/*if(artnet.frameslues==1) //because we already did a getframe();
{
Serial.println("Recording has started");
Serial.printf("Filename:%s\n",filename);
}*/
//}
//record_status=digitalRead(PIN_RECORD);
//record_status=1;
}
if(!new_record)
{
/* uint32_t g=millis();
Serial.printf("%d %d\n",g,record_duration);
record_duration=g-record_duration;*/
myFile.close();
Serial.println("Recording stopped ...");
Serial.printf("frames lues:%d lost frames:%d framedread %d duration:%ld\n",artnet.frameslues,artnet.lostframes,artnet.nbframeread,record_duration);
//Serial.printf("time per frame %f\n",(float)deb/(artnet.nbframeread));
artnet.nbframeread=0;
artnet.frameslues=0;
artnet.lostframes=0;
deb=0;
stopped=true;
new_record=true;
recordingnumber++;
switch_record_mode=false;
first_frame_record=false;
//lcd.clear();
//lcd.setCursor(0, 0);
//lcd.print("REC OK");
//lcd.setCursor(0, 1);
//lcd.print(filename);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment