Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VortexEngine/src/Buttons/Buttons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Button Buttons::m_buttons[NUM_BUTTONS];

bool Buttons::init()
{
// initialize the button on pins 9/10/11
// initialize the button on pins 5/6/7
if (!m_buttons[0].init(5) ||
!m_buttons[1].init(6) ||
!m_buttons[2].init(7)) {
Expand Down
5 changes: 5 additions & 0 deletions VortexEngine/src/Menus/MainMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ void MainMenu::open()
m_isOpen = true;
}

void MainMenu::close()
{
m_isOpen = false;
}

bool MainMenu::isOpen()
{
return m_isOpen;
Expand Down
1 change: 1 addition & 0 deletions VortexEngine/src/Menus/MainMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class MainMenu

// open the main menu
static void open();
static void close();
static bool isOpen();
private:
static void pressLeft();
Expand Down
68 changes: 67 additions & 1 deletion VortexEngine/src/Menus/MenuList/EditorConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
#include "../../Serial/Serial.h"
#include "../../Storage/Storage.h"
#include "../../Wireless/VLSender.h"
#include "../../Wireless/VLReceiver.h"
#include "../../Time/TimeControl.h"
#include "../../Time/Timings.h"
#include "../../Colors/Colorset.h"
#include "../../Modes/Modes.h"
#include "../../Modes/Mode.h"
Expand All @@ -16,7 +18,8 @@

EditorConnection::EditorConnection(const RGBColor &col, bool advanced) :
Menu(col, advanced),
m_state(STATE_DISCONNECTED)
m_state(STATE_DISCONNECTED),
m_timeOutStartTime(0)
{
}

Expand Down Expand Up @@ -182,6 +185,16 @@ Menu::MenuAction EditorConnection::run()
SerialComs::write(EDITOR_VERB_TRANSMIT_VL_ACK);
m_state = STATE_IDLE;
break;
case STATE_LISTEN_MODE_VL:
showReceiveModeVL();
receiveModeVL();
break;
case STATE_LISTEN_MODE_VL_DONE:
// done transmitting
m_receiveBuffer.clear();
SerialComs::write(EDITOR_VERB_LISTEN_VL_ACK);
m_state = STATE_IDLE;
break;
}
return MENU_CONTINUE;
}
Expand All @@ -196,6 +209,57 @@ void EditorConnection::sendCurModeVL()
m_state = STATE_TRANSMIT_MODE_VL;
}

void EditorConnection::listenModeVL()
{
#if VL_ENABLE_SENDER == 1
// immediately load the mode and send it now
VLReceiver::beginReceiving();
#endif
m_state = STATE_LISTEN_MODE_VL;
}

void EditorConnection::receiveModeVL()
{
// if reveiving new data set our last data time
if (VLReceiver::onNewData()) {
m_timeOutStartTime = Time::getCurtime();
// if our last data was more than time out duration reset the recveiver
} else if (m_timeOutStartTime > 0 && (m_timeOutStartTime + MAX_TIMEOUT_DURATION) < Time::getCurtime()) {
VLReceiver::resetVLState();
m_timeOutStartTime = 0;
return;
}
// check if the VLReceiver has a full packet available
if (!VLReceiver::dataReady()) {
// nothing available yet
return;
}
DEBUG_LOG("Mode ready to receive! Receiving...");
// receive the VL mode into the current mode
if (!VLReceiver::receiveMode(&m_previewMode)) {
ERROR_LOG("Failed to receive mode");
return;
}
DEBUG_LOGF("Success receiving mode: %u", m_previewMode.getPatternID());
Modes::updateCurMode(&m_previewMode);
ByteStream modeBuffer;
m_previewMode.saveToBuffer(modeBuffer);
SerialComs::write(modeBuffer);
m_state = STATE_LISTEN_MODE_VL_DONE;
}

void EditorConnection::showReceiveModeVL()
{
if (VLReceiver::isReceiving()) {
// using uint32_t to avoid overflow, the result should be within 10 to 255
//Leds::setAll(RGBColor(0, VLReceiver::percentReceived(), 0));
Leds::setRange(LED_0, (LedPos)(VLReceiver::percentReceived() / 10), RGB_GREEN6);
Leds::setRange(LED_10, (LedPos)(LED_10 + (VLReceiver::percentReceived() / 10)), RGB_GREEN6);
} else {
Leds::setAll(RGB_WHITE0);
}
}

// handlers for clicks
void EditorConnection::onShortClick()
{
Expand Down Expand Up @@ -321,5 +385,7 @@ void EditorConnection::handleCommand()
m_state = STATE_CLEAR_DEMO;
} else if (receiveMessage(EDITOR_VERB_TRANSMIT_VL)) {
sendCurModeVL();
} else if (receiveMessage(EDITOR_VERB_LISTEN_VL)) {
listenModeVL();
}
}
8 changes: 8 additions & 0 deletions VortexEngine/src/Menus/MenuList/EditorConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class EditorConnection : public Menu

// broadcast the current preview mode over VL
void sendCurModeVL();
void listenModeVL();

// handlers for clicks
void onShortClick() override;
Expand All @@ -34,6 +35,8 @@ class EditorConnection : public Menu
void handleCommand();
bool receiveMessage(const char *message);
void clearDemo();
void receiveModeVL();
void showReceiveModeVL();

enum EditorConnectionState {
// the editor is not connec
Expand Down Expand Up @@ -66,12 +69,17 @@ class EditorConnection : public Menu
// transmit the mode over visible light
STATE_TRANSMIT_MODE_VL,
STATE_TRANSMIT_MODE_VL_DONE,

STATE_LISTEN_MODE_VL,
STATE_LISTEN_MODE_VL_DONE,
};

// state of the editor
EditorConnectionState m_state;
// the data that is received
ByteStream m_receiveBuffer;
// receiver timeout
uint32_t m_timeOutStartTime;
};

#endif
6 changes: 3 additions & 3 deletions VortexEngine/src/Modes/Modes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ void Modes::play()
nextModeSkipEmpty();
}
// shortclick cycles to the next mode
if (g_pButtonM->onShortClick()) {
Menus::openMenuSelection();
}
//if (g_pButtonM->onShortClick()) {
// Menus::openMenuSelection();
//}
// shortclick cycles to the next mode
if (g_pButtonL->onShortClick()) {
previousMode();
Expand Down
5 changes: 5 additions & 0 deletions VortexEngine/src/VortexConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,11 @@
// the response from the device when it's done transmitting the mode
#define EDITOR_VERB_TRANSMIT_VL_ACK "n"

// when the pc wants the chromadeck to listen for a mode from the duos
#define EDITOR_VERB_LISTEN_VL "o"
// and the response for when it's done fetching a duo mode
#define EDITOR_VERB_LISTEN_VL_ACK "p"

// ===================================================================
// Manually Configured Sizes
//
Expand Down
4 changes: 2 additions & 2 deletions VortexEngine/src/Wireless/IRConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
//
// Whether to enable the Infrared system as a whole
//
#define IR_ENABLE_SENDER 0
#define IR_ENABLE_RECEIVER 0
#define IR_ENABLE_SENDER 1
#define IR_ENABLE_RECEIVER 1

// the size of IR blocks in bits
#define IR_DEFAULT_BLOCK_SIZE 32
Expand Down
48 changes: 23 additions & 25 deletions VortexEngine/src/Wireless/VLReceiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,33 @@ uint32_t VLReceiver::m_previousBytes = 0;
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/adc.h"
#include "esp_adc_cal.h"
#include "esp_log.h"
#include "esp_timer.h"

#include "../Serial/Serial.h"

// ADC and timer configuration
#define ADC_CHANNEL ADC1_CHANNEL_1 // Update this based on the actual ADC channel used
#define TIMER_INTERVAL_MICRO_SEC 10000 // Check every 10ms, adjust as needed for your application
#define ADC_ATTEN ADC_ATTEN_DB_0
#define ADC_WIDTH ADC_WIDTH_BIT_12
#define TIMER_INTERVAL_MICRO_SEC 1000 // Check every 10ms, adjust as needed for your application

// Timer handle as a global variable for control in beginReceiving and endReceiving
esp_timer_handle_t periodic_timer = nullptr;
esp_adc_cal_characteristics_t adc_chars;

#define MIN_THRESHOLD 200
#define BASE_OFFSET 100
#define THRESHOLD_BEGIN (MIN_THRESHOLD + BASE_OFFSET)
// the sample count exponent, so 5 means 2^5 = 32 samples
// 0 NONE No accumulation > doesn't work
// 1 ACC2 2 results accumulated > doesn't work
// 2 ACC4 4 results accumulated > works okay
// 3 ACC8 8 results accumulated > works decent
// 4 ACC16 16 results accumulated > works very well
// 5 ACC32 32 results accumulated > works best
// 6 ACC64 64 results accumulated > doesn't work
#define SAMPLE_COUNT 5
// the threshold needs to start high then it will be automatically pulled down
uint32_t threshold = THRESHOLD_BEGIN;
void VLReceiver::adcCheckTimerCallback(void *arg)
{
static bool wasAboveThreshold = false;
uint32_t val = adc1_get_raw(ADC_CHANNEL);
uint32_t raw = adc1_get_raw(ADC_CHANNEL);
uint32_t val = esp_adc_cal_raw_to_voltage(raw, &adc_chars);

if (val > MIN_THRESHOLD && val < (threshold + BASE_OFFSET)) {
threshold = val + BASE_OFFSET;
}
Expand All @@ -65,8 +62,10 @@ bool VLReceiver::init()
{
#ifdef VORTEX_EMBEDDED
// Initialize ADC for GPIO1 (or appropriate pin connected to your light sensor)
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN_DB_0);
adc1_config_width(ADC_WIDTH);
adc1_config_channel_atten(ADC_CHANNEL, ADC_ATTEN);
memset(&adc_chars, 0, sizeof(adc_chars));
esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN, ADC_WIDTH, 0, &adc_chars);
#endif
return m_vlData.init(VL_RECV_BUF_SIZE);
}
Expand Down Expand Up @@ -134,16 +133,15 @@ bool VLReceiver::receiveMode(Mode *pMode)
bool VLReceiver::beginReceiving()
{
#ifdef VORTEX_EMBEDDED
if (periodic_timer != nullptr) {
if (periodic_timer) {
DEBUG_LOG("VL Reception already running.");
return false; // Timer is already running
}
// Initialize timer for periodic ADC checks
const esp_timer_create_args_t periodic_timer_args = {
.callback = (void (*)(void*))&VLReceiver::adcCheckTimerCallback,
.name = "adc_check_timer"
.callback = &VLReceiver::adcCheckTimerCallback,
.name = "adc_check_timer",
};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, TIMER_INTERVAL_MICRO_SEC));
#endif
Expand Down Expand Up @@ -213,25 +211,25 @@ void VLReceiver::recvPCIHandler()
// check previous time for validity
if (!m_prevTime || m_prevTime > now) {
m_prevTime = now;
DEBUG_LOG("Bad first time diff, resetting...");
//DEBUG_LOG("Bad first time diff, resetting...");
resetVLState();
return;
}
DEBUG_LOGF("Received: %u", m_pinState);
//DEBUG_LOGF("Received: %u", m_pinState);
// calc time difference between previous change and now
uint32_t diff = (uint32_t)(now - m_prevTime);
// and update the previous changetime for next loop
m_prevTime = now;
// handle the bliank duration and process it
//handleVLTiming(diff);
handleVLTiming(diff);
}

// state machine that can be fed VL timings to parse them and interpret the intervals
void VLReceiver::handleVLTiming(uint32_t diff)
{
// if the diff is too long or too short then it's not useful
if ((diff > VL_HEADER_MARK_MAX && m_recvState < READING_DATA_MARK) || diff < VL_TIMING_MIN) {
DEBUG_LOGF("bad delay: %u, resetting...", diff);
//DEBUG_LOGF("bad delay: %u, resetting...", diff);
resetVLState();
return;
}
Expand All @@ -240,15 +238,15 @@ void VLReceiver::handleVLTiming(uint32_t diff)
if (diff >= VL_HEADER_SPACE_MIN && diff <= VL_HEADER_MARK_MAX) {
m_recvState = WAITING_HEADER_SPACE;
} else {
DEBUG_LOGF("Bad header mark %u, resetting...", diff);
//DEBUG_LOGF("Bad header mark %u, resetting...", diff);
resetVLState();
}
break;
case WAITING_HEADER_SPACE:
if (diff >= VL_HEADER_SPACE_MIN && diff <= VL_HEADER_MARK_MAX) {
m_recvState = READING_DATA_MARK;
} else {
DEBUG_LOGF("Bad header space %u, resetting...", diff);
//DEBUG_LOGF("Bad header space %u, resetting...", diff);
resetVLState();
}
break;
Expand All @@ -262,7 +260,7 @@ void VLReceiver::handleVLTiming(uint32_t diff)
m_recvState = READING_DATA_MARK;
break;
default: // ??
DEBUG_LOGF("Bad receive state: %u", m_recvState);
//DEBUG_LOGF("Bad receive state: %u", m_recvState);
break;
}
}
Expand All @@ -273,7 +271,7 @@ void VLReceiver::resetVLState()
m_recvState = WAITING_HEADER_MARK;
// zero out the receive buffer and reset bit receiver position
m_vlData.reset();
DEBUG_LOG("VL State Reset");
//DEBUG_LOG("VL State Reset");
}

#endif
2 changes: 1 addition & 1 deletion VortexEngine/src/Wireless/VLReceiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class VLReceiver
static uint32_t m_previousBytes;

#ifdef VORTEX_EMBEDDED
void adcCheckTimerCallback(void *arg);
static void adcCheckTimerCallback(void *arg);
#endif

#ifdef VORTEX_LIB
Expand Down