pupilometer/src/lightingFirmware/esp32_test0/esp32_test0.ino

402 lines
11 KiB
C++

// Include Section
#include "esp_dmx.h"
#include "rdm/controller.h"
#include "rdm/responder.h"
#include "UUID.h"
#include "EEPROM.h"
#define INTERRUPT_PIN 0
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
bool debugMode = true;
int bleCharCount;
const int channelPerLamp = 4;
const int expectedLampCount = 25;
const int dmxPacketSize = channelPerLamp * expectedLampCount + 1; //
struct Button {
const uint8_t PIN;
uint32_t numberKeyPresses;
bool pressed;
};
uint8_t dmxData[DMX_PACKET_SIZE] = {0};
BLEServer* pServer = NULL;
bool deviceConnected = false;
bool oldDeviceConnected = false;
uint16_t SERVICE_UUID = 20241115;
const int panelAmount = 25;
BLECharacteristic* pCharacteristics[panelAmount];
char* CHARACTERISTIC_UUIDS[panelAmount];
class MyServerCallbacks: public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
}
};
// Defining BOOT button on ESP32 as our built-in button.
Button button1 = {INTERRUPT_PIN, 0, false};
int mode = 0;
const int modeAmount = 16;
uint8_t brightnessMax = 20;
uint8_t universalBrightness = 10;
uint8_t dataSeq[modeAmount][DMX_PACKET_SIZE] =
{
{
0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0
},
{
0,
0,universalBrightness,0,0,
0,universalBrightness,0,0,
0,universalBrightness,0,0,
0,universalBrightness,0,0,
0,universalBrightness,0,0,
0,universalBrightness,0,0,
0,universalBrightness,0,0,
0,universalBrightness,0,0,
0,universalBrightness,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0
},
{
0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0
},
{
0,
universalBrightness,0,0,0, // Orange
0,universalBrightness,0,0, // White
0,universalBrightness,0,0, // White
0,0,universalBrightness,0, // Blue
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,0,universalBrightness,0,
0,universalBrightness,0,0,
//End Inner Round
//Start Outer Round
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0
},
{
0,
//Start Inner Round
0,0,universalBrightness,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
0,0,0,0,
//End Inner Round
//Start Outer Round
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0,
universalBrightness,0,0,0
}
}
;
void IRAM_ATTR isr() {
button1.pressed = true;
};
void ledBlink(int interval, int pinNumber) {
digitalWrite(
pinNumber,
!digitalRead(pinNumber)
);
delay(interval);
};
void dmxSetup() {
const dmx_port_t dmx_num = DMX_NUM_1;
Serial.printf("\nSetting up DMX Port %d", dmx_num);
// First, use the default DMX configuration...
dmx_config_t config = DMX_CONFIG_DEFAULT;
// Declare Personality RGBW
const int personality_count = 1;
Serial.print("\nDefining DMX Personality... ");
dmx_personality_t personalities[] = {
{4, "RGBW"}
};
Serial.print("Done");
Serial.print("\nInstalling DMX Driver... ");
// ...install the DMX driver...
dmx_driver_install(dmx_num, &config, personalities, personality_count);
Serial.print("Done");
// ...and then set the communication pins!
const int tx_pin = 23;
const int rx_pin = 22;
const int rts_pin = 21;
Serial.printf("\nSetting up pin %d as Transmit Pin, pin %d as Receive Pin and pin %d as RTS Pin... ", tx_pin, rx_pin, rts_pin);
dmx_set_pin(dmx_num, tx_pin, rx_pin, rts_pin);
Serial.print("Done\n");
}
void serialRead(){
String incomingByte;
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.readStringUntil('\r\n');
Serial.print("\nI received: ");
Serial.print(incomingByte);
mode = incomingByte.toInt();
}
}
void setup() {
Serial.begin(115200);
delay(2000);
Serial.print("\nIf you receive this message, ESP32 module has finished setting up Serial Interface for communication.");
pinMode(INTERRUPT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), isr, RISING);
//Begin of the DMX Setup
const dmx_port_t dmx_num = DMX_NUM_1;
dmxSetup();
Serial.println("Welcome to Pupilometer LED Billboard!");
const int array_size = 25;
rdm_uid_t uids[array_size];
// This function blocks and may take some time to complete!
Serial.printf("Attempting to Discover the Existing DMX Network... ");
int num_uids = rdm_discover_devices_simple(DMX_NUM_1, uids, array_size);
Serial.printf("Done!\n");
Serial.printf("Discovery found %i UIDs as following:\n", num_uids);
for (int i = 0; i < num_uids; i++){
printf(UIDSTR "\n", UID2STR(uids[i]));
};
// Create the BLE Device
BLEDevice::init("Pupilometer LED Billboard");
// Create the BLE Server
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pService = pServer->createService(SERVICE_UUID,52);
const bool debugMode = false;
// Serial.printf(debugMode);
// Create a BLE Characteristic
Serial.printf("\nCalculating BLE Charateristic Count");
bleCharCount = (panelAmount * debugMode) + !debugMode;
Serial.printf("\nCalculating BLE MTU ...");
uint16_t bleMTU = ((panelAmount * 3) / bleCharCount) + 3;
Serial.printf("\nSetting BLE MTU to %i bytes... ", bleMTU);
BLEDevice::setMTU(bleMTU + 3);
Serial.printf("Done!\n");
for (uint32_t i = 0; i < bleCharCount; i++){
//UUID uuid;
//uuid.seed(i+1);
//uuid.generate();
//Serial.printf("Creating BLE Characteristic with UUID %s ...", BLEUUID(i+1));
pCharacteristics[i] = pService->createCharacteristic(
i+1,
// BLEUUID(uuid.toCharArray()),
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
Serial.printf("Created BLE Characteristic with UUID %s ...", pCharacteristics[i]->getUUID().toString().c_str());
// pCharacteristics[i]->addDescriptor(new BLE2902());
// Serial.printf("Done\n");
};
// Start the service
pService->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x0); // set value to 0x00 to not advertise this parameter
BLEDevice::startAdvertising();
}
void loop() {
// Save Old Mode
int modeOld = mode;
int msgSize;
uint8_t* btMessage[bleCharCount];
// uint8_t dmxData[DMX_PACKET_SIZE] = {0};
// notify changed value
if (deviceConnected) {
}
// disconnecting
if (!deviceConnected && oldDeviceConnected) {
delay(500); // give the bluetooth stack the chance to get things ready
pServer->startAdvertising(); // restart advertising
Serial.println("Start advertising");
oldDeviceConnected = deviceConnected;
}
// connecting
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
}
// Serial.printf("\nConstructing Payload using ");
// Serial.printf("Bluetooth Data ...");
if (button1.pressed){
if (mode < modeAmount - 1){mode++;} else {mode = 0;};
// Increment the value of each slot, excluding the start code.
button1.pressed = false; // Reset button status to FALSE
};
serialRead();
if (modeOld != mode){
Serial.printf("\nChanging Lighting Preset to Preset %d", mode);
uint8_t lampData[DMX_PACKET_SIZE / 4 * 3];
Serial.printf("\nDetected preset %i size: %i", mode, sizeof(dataSeq[mode]));
for (int i = 0; i < sizeof(dataSeq[mode]); i++){
dmxData[i] = dataSeq[mode][i];
int sublampIndex = i % 4;
//Serial.printf("[%i]", sublampIndex, j);
if (sublampIndex > 0) {
int j = (i / 4) * 3 + sublampIndex - 1;
Serial.printf("[%i](%i)", j, sublampIndex);
lampData[j] = dataSeq[mode][i];
}
};
pCharacteristics[0]->setValue(lampData, expectedLampCount * 3);
}
Serial.printf("\nConstructing DMX Payload with size ");
for (int i = 0; i < bleCharCount; i++){
btMessage[i] = pCharacteristics[i]->getData();
msgSize = pCharacteristics[i]->getLength();
Serial.printf("%i bytes ", msgSize);
for (int j = 0; j < msgSize; j++){
int packet = btMessage[i][j];
int lampSum = i*3 + j;
int dmxAddress = (lampSum / 3) * 4 + lampSum % 3 + 1;
dmxData[dmxAddress] = packet;
// Serial.printf("[[%i,%i] %i - %i] ",i , j, dmxAddress, packet);
};
};
Serial.printf("\n");
// Serial.printf(" Done");
// Wait until the packet is finished being sent before proceeding.
dmx_wait_sent(DMX_NUM_1, DMX_TIMEOUT_TICK);
// Now write the packet synchronously!
dmx_write(DMX_NUM_1, dmxData, DMX_PACKET_SIZE);
dmx_send(DMX_NUM_1);
}