// nějaké přízpůsobení, ISR ok, čte PCF , ale nepíše mi do PCA pwm
#include <Wire.h>
#include <WiFi.h>
#include "time.h"
// Network Credentials
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASSWORD";
// NTP Server Settings
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600; // Adjust for your Time Zone (e.g., 3600 = UTC+1)
const int daylightOffset_sec = 3600; // Adjust for Daylight Savings (e.g., 3600 = +1 hour)
// Hardware Pins & Addresses (Same as before)
#define PCF8575_ADDR 0x21
#define PCA9685_ADDR 0x41
#define INT_PIN 32
#define PCA9685_MODE1 0x00
#define LED0_ON_L 0x06
#define FADE_STEP 25
#define TICK_DELAY_MS 10
struct LedMessage {
uint8_t channel;
uint16_t pwmValue;
bool pinState;
};
SemaphoreHandle_t pcfSemaphore = NULL;
QueueHandle_t ledQueue = NULL;
uint16_t currentPWM[16] = {0};
uint16_t targetPWM[16] = {0};
// --- Existing Hardware Driver Functions (Unchanged) ---
void IRAM_ATTR onPcfInterrupt() {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(pcfSemaphore, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken) portYIELD_FROM_ISR();
}
uint16_t pcfRead() {
Serial.println("pcfRead");
Wire.requestFrom(PCF8575_ADDR, 2);
if (Wire.available() == 2) return (Wire.read() | (Wire.read() << 8));
return 0xFFFF;
}
void pcfWrite(uint16_t data) {
Wire.beginTransmission(PCF8575_ADDR);
Wire.write(data & 0xFF);
Wire.write((data >> 8) & 0xFF);
Wire.endTransmission();
}
void pca9685Setup() {
Wire.beginTransmission(PCA9685_ADDR);
Wire.write(PCA9685_MODE1);
Wire.write(0x20);
Wire.endTransmission();
vTaskDelay(pdMS_TO_TICKS(5));
}
void setLedPwm(uint8_t channel, uint16_t pwmValue) {
Serial.println("Pwm Write");
if (pwmValue > 4095) pwmValue = 4095;
uint8_t regAddress = LED0_ON_L + (channel * 4);
Wire.beginTransmission(PCA9685_ADDR);
Wire.write(regAddress);
Wire.write(0x00); Wire.write(0x00);
Wire.write(pwmValue & 0xFF); Wire.write((pwmValue >> 8) & 0xFF);
Wire.endTransmission();
}
void vInputReaderTask(void *pvParameters) {
uint16_t lastPinStates = 0xFFFF;
Serial.println(" Reader Task ");
for (;;) {
if (xSemaphoreTake(pcfSemaphore, portMAX_DELAY) == pdTRUE) {
uint16_t currentPinStates = pcfRead();
bool currentP0 = (currentPinStates & (1 << 0)) != 0;
if (currentP0 != ((lastPinStates & (1 << 0)) != 0)) {
LedMessage msg = {0, (uint16_t)(!currentP0 ? 4000 : 0), currentP0};
xQueueSend(ledQueue, &msg, 0);
}
lastPinStates = currentPinStates;
}
}
// vTaskDelay(100);
}
void vLedOutputTask(void *pvParameters) {
LedMessage receivedMsg;
TickType_t xLastWakeTime = xTaskGetTickCount();
for (;;) {
if (xQueueReceive(ledQueue, &receivedMsg, pdMS_TO_TICKS(TICK_DELAY_MS)) == pdTRUE) {
if (receivedMsg.channel < 16) targetPWM[receivedMsg.channel] = receivedMsg.pwmValue;
}
for (uint8_t i = 0; i < 16; i++) {
if (currentPWM[i] != targetPWM[i]) {
if (currentPWM[i] < targetPWM[i]) {
currentPWM[i] = (targetPWM[i] - currentPWM[i] < FADE_STEP) ? targetPWM[i] : currentPWM[i] + FADE_STEP;
} else {
currentPWM[i] = (currentPWM[i] - targetPWM[i] < FADE_STEP) ? targetPWM[i] : currentPWM[i] - FADE_STEP;
}
setLedPwm(i, currentPWM[i]);
}
}
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(TICK_DELAY_MS));
}
}
// --- NEW TASK: Wi-Fi, NTP, and Serial Display Engine (Runs on Core 0) ---
void vWifiNtpDisplayTask(void *pvParameters) {
Serial.print("[WiFi Task] Connecting to ");
// Serial.println(ssid);
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
vTaskDelay(pdMS_TO_TICKS(500));
Serial.print(".");
}
Serial.println("\n[WiFi Task] Connected! Syncing time with NTP...");
// Configures the internal ESP32 RTC to use NTP
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
struct tm timeinfo;
// Wait until time is successfully grabbed from the network
while(!getLocalTime(&timeinfo)){
Serial.println("[WiFi Task] Failed to obtain time, retrying...");
vTaskDelay(pdMS_TO_TICKS(2000));
}
Serial.println("[WiFi Task] Time Synced Successfully!");
// Once synced, you can optionally disconnect WiFi to save power,
// or keep it running. The ESP32 internal clock tracks time seamlessly now.
for (;;) {
if (getLocalTime(&timeinfo)) {
// Print formatted output directly to Serial (or your hardware serial display)
// Format details: %Y = Year, %m = Month, %d = Day, %H = Hour, %M = Minute, %S = Second
Serial.printf("[DISPLAY] Date: %04d-%02d-%02d | Time: %02d:%02d:%02d\n",
timeinfo.tm_year + 1900, timeinfo.tm_mon + 1, timeinfo.tm_mday,
timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
}
// Update the display refresh rate (e.g., exactly once per second)
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void setup() {
Serial.begin(115200);
Wire.begin(21, 22);
Wire.setClock(400000);
pcfWrite(0xFFFF);
pca9685Setup();
for (int i = 0; i < 16; i++) setLedPwm(i, 0);
pcfSemaphore = xSemaphoreCreateBinary();
ledQueue = xQueueCreate(20, sizeof(LedMessage));
if (pcfSemaphore != NULL && ledQueue != NULL) {
// --- CORE 1 TASKS (Hardware Real-Time Loops) ---
xTaskCreatePinnedToCore(vInputReaderTask, "ReaderTask", 3000, NULL, 3, NULL, 1);
xTaskCreatePinnedToCore(vLedOutputTask, "OutputTask", 3000, NULL, 2, NULL, 1);
// --- CORE 0 TASK (Network & Non-time-critical Operations) ---
xTaskCreatePinnedToCore(vWifiNtpDisplayTask, "WifiNtpTask", 4000, NULL, 1, NULL, 0);
pinMode(INT_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(INT_PIN), onPcfInterrupt, FALLING);
xSemaphoreGive(pcfSemaphore);
}
}
void loop() {
vTaskDelay(pdMS_TO_TICKS(1000));
}Loading
esp32-devkit-c-v4
esp32-devkit-c-v4
70 addr 000
0x20 addr 000
LCD 0x27
0x21 001
pwm1 0x41 - 00001