first commit
This commit is contained in:
+42
@@ -0,0 +1,42 @@
|
||||
# PlatformIO
|
||||
.pio/
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch/
|
||||
|
||||
# Compilation
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.exe
|
||||
|
||||
# IDE
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Backup files
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
|
||||
# Configuration sensible (décommentez si nécessaire)
|
||||
# src/config.h
|
||||
# include/secrets.h
|
||||
|
||||
# Documentation générée
|
||||
docs/html/
|
||||
docs/latex/
|
||||
|
||||
# Archives
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# Fichiers de développement
|
||||
test_*
|
||||
debug_*
|
||||
temp_*
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.ino": "cpp",
|
||||
"platformio.ini": "ini"
|
||||
},
|
||||
"C_Cpp.default.configurationProvider": "ms-vscode.vscode-json",
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true,
|
||||
"files.autoSave": "afterDelay",
|
||||
"files.autoSaveDelay": 1000,
|
||||
"terminal.integrated.defaultProfile.osx": "zsh",
|
||||
"platformio-ide.forceUploadAndMonitor": false,
|
||||
"platformio-ide.autoPreloadEnvTasks": true,
|
||||
"explorer.fileNesting.enabled": true,
|
||||
"explorer.fileNesting.patterns": {
|
||||
"platformio.ini": ".vscode/*, lib/*, test/*, .pio/*, .gitignore",
|
||||
"README.md": "*.md"
|
||||
},
|
||||
"stm32-for-vscode.openOCDPath": false,
|
||||
"stm32-for-vscode.armToolchainPath": false
|
||||
}
|
||||
Vendored
+200
@@ -0,0 +1,200 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "PlatformIO: Build Main Project",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "main"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Upload Main Project",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "main", "--target", "upload"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Test RTC Module",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "rtc_test", "--target", "upload"],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Test P10 Matrix",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "p10_test", "--target", "upload"],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Erase NVS Memory",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "nvs_erase", "--target", "upload"],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Test Cascade (2 panels)",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "test_cascade", "--target", "upload"],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Cascade 2x1 (64x16)",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "cascade_2x1", "--target", "upload"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Cascade 3x1 (96x16)",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "cascade_3x1", "--target", "upload"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Cascade 4x1 (128x16)",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "cascade_4x1", "--target", "upload"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Cascade 2x2 (64x32)",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "cascade_2x2", "--target", "upload"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Cascade 6x1 (192x16)",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "cascade_6x1", "--target", "upload"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Cascade 8x1 (256x16)",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "-e", "cascade_8x1", "--target", "upload"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$gcc"
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Monitor Serial",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["device", "monitor"],
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"isBackground": true
|
||||
},
|
||||
{
|
||||
"label": "PlatformIO: Clean Project",
|
||||
"type": "shell",
|
||||
"command": "pio",
|
||||
"args": ["run", "--target", "clean"],
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
# Guide des Panneaux P10 en Cascade
|
||||
|
||||
## 🔗 Vue d'ensemble
|
||||
|
||||
Ce projet supporte maintenant plusieurs panneaux P10 connectés en cascade pour créer des affichages plus larges ou plus hauts.
|
||||
|
||||
## 📐 Configurations Supportées
|
||||
|
||||
### Configurations Horizontales (recommandées)
|
||||
- **1x1** : 32x16 pixels (1 panneau) - Configuration standard
|
||||
- **2x1** : 64x16 pixels (2 panneaux) - Ideal pour texte plus long
|
||||
- **3x1** : 96x16 pixels (3 panneaux) - Texte défilant étendu
|
||||
- **4x1** : 128x16 pixels (4 panneaux) - Affichage type bandeau
|
||||
- **6x1** : 192x16 pixels (6 panneaux) - Grand bandeau
|
||||
- **8x1** : 256x16 pixels (8 panneaux) - Très grand bandeau
|
||||
|
||||
### Configurations Verticales/Mixtes
|
||||
- **2x2** : 64x32 pixels (4 panneaux) - Affichage carré
|
||||
- **1x2** : 32x32 pixels (2 panneaux) - Plus de hauteur
|
||||
- **4x2** : 128x32 pixels (8 panneaux) - Grand affichage
|
||||
|
||||
## 🛠️ Connexion Physique
|
||||
|
||||
### Connexion en Cascade (Chaînage)
|
||||
```
|
||||
ESP32 ──── Panneau 1 ──── Panneau 2 ──── Panneau 3 ──── ...
|
||||
(Premier) (Deuxième) (Troisième)
|
||||
```
|
||||
|
||||
### Détails de Connexion
|
||||
1. **Premier panneau** : Connecté directement à l'ESP32 (voir WIRING.md)
|
||||
2. **Panneaux suivants** : Connectés via les ports de sortie du panneau précédent
|
||||
3. **Alimentation** : Chaque panneau doit être alimenté en 5V individuellement
|
||||
|
||||
### Important - Alimentation
|
||||
```
|
||||
⚠️ ATTENTION ALIMENTATION !
|
||||
|
||||
Chaque panneau P10 consomme environ 1-2A sous 5V
|
||||
- 2 panneaux : 5V/4A minimum
|
||||
- 4 panneaux : 5V/8A minimum
|
||||
- 6 panneaux : 5V/12A minimum
|
||||
|
||||
Utilisez une alimentation adaptée !
|
||||
```
|
||||
|
||||
## 🎯 Compilation pour Cascade
|
||||
|
||||
### Commandes PlatformIO
|
||||
|
||||
```bash
|
||||
# 2 panneaux horizontaux (64x16)
|
||||
pio run -e cascade_2x1 --target upload
|
||||
|
||||
# 3 panneaux horizontaux (96x16)
|
||||
pio run -e cascade_3x1 --target upload
|
||||
|
||||
# 4 panneaux horizontaux (128x16)
|
||||
pio run -e cascade_4x1 --target upload
|
||||
|
||||
# 2x2 panneaux (64x32)
|
||||
pio run -e cascade_2x2 --target upload
|
||||
|
||||
# 6 panneaux horizontaux (192x16)
|
||||
pio run -e cascade_6x1 --target upload
|
||||
|
||||
# 8 panneaux horizontaux (256x16)
|
||||
pio run -e cascade_8x1 --target upload
|
||||
|
||||
# Test de cascade (2 panneaux)
|
||||
pio run -e test_cascade --target upload
|
||||
```
|
||||
|
||||
### Configuration Personnalisée
|
||||
|
||||
Pour une configuration non-standard, modifiez `platformio.ini` :
|
||||
|
||||
```ini
|
||||
[env:custom_cascade]
|
||||
extends = env:main
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMATRIX_WIDTH=32 ; Largeur d'un panneau
|
||||
-DMATRIX_HEIGHT=16 ; Hauteur d'un panneau
|
||||
-DMATRIX_PANELS_X=5 ; Nombre panneaux horizontaux
|
||||
-DMATRIX_PANELS_Y=1 ; Nombre panneaux verticaux
|
||||
-DCASCADE_MODE=1
|
||||
```
|
||||
|
||||
## 🧪 Test des Panneaux
|
||||
|
||||
### Test d'Alignement
|
||||
```bash
|
||||
pio run -e test_cascade --target upload
|
||||
```
|
||||
|
||||
Ce test affiche :
|
||||
1. **Bordures** : Contour de chaque panneau
|
||||
2. **Numérotation** : P1, P2, P3... sur chaque panneau
|
||||
3. **Couleurs** : Test de toutes les couleurs
|
||||
4. **Texte défilant** : Test sur toute la largeur
|
||||
|
||||
### Vérifications Visuelles
|
||||
- ✅ Tous les panneaux s'allument
|
||||
- ✅ Bordures alignées correctement
|
||||
- ✅ Numérotation séquentielle (P1, P2, P3...)
|
||||
- ✅ Couleurs uniformes sur tous les panneaux
|
||||
- ✅ Texte défile sans coupure
|
||||
|
||||
## ⚙️ Ajustements Automatiques
|
||||
|
||||
### Luminosité Auto-Adaptée
|
||||
```cpp
|
||||
// Le code ajuste automatiquement la luminosité :
|
||||
1-2 panneaux : 125/255 (luminosité normale)
|
||||
3-4 panneaux : 100/255 (réduite)
|
||||
5-6 panneaux : 80/255 (plus réduite)
|
||||
7+ panneaux : 60/255 (très réduite)
|
||||
```
|
||||
|
||||
### Centrage Automatique
|
||||
- **Horloge** : Centrée automatiquement sur la largeur totale
|
||||
- **Texte défilant** : Utilise toute la largeur disponible
|
||||
- **Interface web** : Fonctionne normalement
|
||||
|
||||
## 🌐 Interface Web Adaptée
|
||||
|
||||
L'interface web fonctionne normalement avec les cascades :
|
||||
- Configuration identique
|
||||
- Texte défilant adapté à la largeur
|
||||
- Couleurs appliquées sur tous les panneaux
|
||||
- Luminosité globale
|
||||
|
||||
## 🔧 Dépannage Cascade
|
||||
|
||||
### Problème : Un panneau ne s'allume pas
|
||||
1. ✅ Vérifiez l'alimentation 5V de chaque panneau
|
||||
2. ✅ Vérifiez les connexions en cascade
|
||||
3. ✅ Testez avec moins de panneaux
|
||||
|
||||
### Problème : Affichage décalé
|
||||
1. ✅ Vérifiez l'ordre des panneaux (P1, P2, P3...)
|
||||
2. ✅ Utilisez le test d'alignement
|
||||
3. ✅ Vérifiez les paramètres PANELS_X et PANELS_Y
|
||||
|
||||
### Problème : Scintillement
|
||||
1. ✅ Réduisez la luminosité
|
||||
2. ✅ Vérifiez l'alimentation (suffisamment puissante ?)
|
||||
3. ✅ Réduisez `PxMATRIX_SPI_FREQUENCY`
|
||||
|
||||
### Problème : Texte coupé
|
||||
1. ✅ Vérifiez que TOTAL_WIDTH est correct
|
||||
2. ✅ Utilisez le test de texte défilant
|
||||
3. ✅ Vérifiez la configuration PANELS_X
|
||||
|
||||
## 📋 Checklist Installation Cascade
|
||||
|
||||
### Étape 1 : Préparation
|
||||
- [ ] Alimentation suffisante calculée (2A × nombre de panneaux)
|
||||
- [ ] Panneaux P10 testés individuellement
|
||||
- [ ] Câbles de connexion préparés
|
||||
|
||||
### Étape 2 : Connexion Physique
|
||||
- [ ] Premier panneau connecté à l'ESP32
|
||||
- [ ] Panneaux en cascade connectés
|
||||
- [ ] Alimentation 5V sur chaque panneau
|
||||
- [ ] Masse commune vérifiée
|
||||
|
||||
### Étape 3 : Configuration Logicielle
|
||||
- [ ] Environnement cascade choisi (ex: cascade_2x1)
|
||||
- [ ] Code compilé et téléversé
|
||||
- [ ] Test d'alignement réussi
|
||||
|
||||
### Étape 4 : Test Final
|
||||
- [ ] Tous les panneaux s'allument
|
||||
- [ ] Numérotation correcte visible
|
||||
- [ ] Horloge centrée correctement
|
||||
- [ ] Texte défile sur toute la largeur
|
||||
- [ ] Interface web accessible
|
||||
|
||||
## 💡 Conseils Optimisation
|
||||
|
||||
### Performance
|
||||
- Plus de panneaux = plus de données à traiter
|
||||
- Réduisez la luminosité si nécessaire
|
||||
- Utilisez une alimentation stable
|
||||
|
||||
### Esthétique
|
||||
- Alignez physiquement les panneaux parfaitement
|
||||
- Utilisez des supports adaptés
|
||||
- Protégez les connexions
|
||||
|
||||
### Fiabilité
|
||||
- Alimentation dimensionnée correctement
|
||||
- Connexions bien fixées
|
||||
- Test avant installation finale
|
||||
|
||||
## 🎨 Exemples d'Utilisation
|
||||
|
||||
### Bandeau d'Information (4x1)
|
||||
```
|
||||
┌─────────────────────────────┐
|
||||
│ 12:34 ESP32 CLOCK │
|
||||
│ Aujourd'hui 15°C - Beau... │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
### Affichage Carré (2x2)
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ 12:34 │
|
||||
│ ESP32 CLOCK │
|
||||
│ │
|
||||
│ Message long... │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
### Grand Bandeau (8x1)
|
||||
```
|
||||
┌───────────────────────────────────────────────────────────┐
|
||||
│ 12:34 - ESP32 DIGITAL CLOCK │
|
||||
│ Très long message défilant avec beaucoup d'informations... │
|
||||
└───────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
La cascade de panneaux P10 permet de créer des affichages personnalisés adaptés à vos besoins !
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 284 KiB |
@@ -0,0 +1,20 @@
|
||||
1. Please enter the "Key" that matches the "Key" in the Arduino code.
|
||||
2. The "Apply Time and Date" button is to set the time and date on the DS3231 RTC module based on the time and date on your device.
|
||||
3. "Display Mode" is the setting for display mode.
|
||||
> Display Mode = 1 is a display mode in which the color of the clock, the color of the scrolling text to display the date
|
||||
(including the name of the day) and the color of the message in
|
||||
the scrolling text can be set manually.
|
||||
> Display Mode = 2 is a display mode in which the color of the clock, the color of the scrolling text to display the date
|
||||
(including the name of the day) and the color of the message in the scrolling text will change sequentially based on the color code
|
||||
list in the Arduino code.
|
||||
4. "Brightness" is the setting to adjust the brightness on the P10 RGB 32x16 panel.
|
||||
5. "Clock Color" is a setting to adjust the color of the clock display (can only be set if display mode = 1).
|
||||
6. "Date Color" is a setting to set the scrolling text display color to display the name of the day and date
|
||||
(can only be set if display mode = 1).
|
||||
7. "Scrolling Text" is a setting to set the message displayed on the scrolling text (after scrolling the text containing the name of
|
||||
the day and date).
|
||||
8. "Text Color" is a setting to set the text color for displaying messages in scrolling text (does not include scrolling text for names of days
|
||||
and dates and can only be set if display mode = 1).
|
||||
9. "Scrolling Speed" is a setting to set the speed of scrolling text (scrolling text for names of days and dates and scrolling text for
|
||||
displaying messages).
|
||||
10. The "Get Settings" button is to get the settings stored in the ESP32 flash memory.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 516 KiB |
@@ -0,0 +1,4 @@
|
||||
- Adafruit BusIO (V1.16.1) by Adafruit : Install via "Manage Libraries" or "Library Manager" in the Arduino IDE with the search keyword "Adafruit BusIO".
|
||||
- RTClib by Adafruit (V2.1.4) : Install via "Manage Libraries" or "Library Manager" in the Arduino IDE with the search keyword "RTClib".
|
||||
- Adafruit GFX Library by Adafruit (V1.11.9) : Install via "Manage Libraries" or "Library Manager" in the Arduino IDE with the search keyword "Adafruit GFX Library".
|
||||
- PxMatrix Library by 2dom (Dominic Buchstaller) (V1.8.2) : https://github.com/2dom/PxMatrix/tree/master
|
||||
+527
@@ -0,0 +1,527 @@
|
||||
const char MAIN_page[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<title>Digital Clcok & Scrolling Text with ESP32 and P10 RGB 32x16</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
html {font-family: Helvetica, sans-serif;}
|
||||
h1 {font-size: 1.1rem; color:#1976D2;}
|
||||
|
||||
label {font-size: 14px;}
|
||||
|
||||
.div_Form {
|
||||
margin: auto;
|
||||
width: 90%;
|
||||
border:1px solid #D8D8D8;
|
||||
border-radius: 10px;
|
||||
background-color: #f2f2f2;
|
||||
padding: 9px 9px;
|
||||
}
|
||||
|
||||
.myButton {
|
||||
display: inline-block;
|
||||
padding: 3px 25px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
color: #fff;
|
||||
background-color: #1976D2;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px #999;
|
||||
}
|
||||
.myButton:hover {background-color: #104d89}
|
||||
.myButton:active {background-color: #104d89; box-shadow: 0 1px #666; transform: translateY(2px);}
|
||||
.myButton:disabled {background-color: #666; box-shadow: 0 1px #666; transform: translateY(2px);}
|
||||
|
||||
.myButtonX {background-color: #ff0000}
|
||||
.myButtonX:hover {background-color: #7a0101}
|
||||
|
||||
.div_Form_Input {display: table; margin: 0px; padding: 0px; box-sizing: border-box;}
|
||||
.div_Input_Text {display: table-cell; width: 100%;}
|
||||
.div_Input_Text > input {width:99.5%; margin-left: 0px; padding-left: 2px; box-sizing: border-box;}
|
||||
|
||||
table, th, td {
|
||||
border: 0px solid black;
|
||||
border-collapse: collapse;
|
||||
font-size: 14px;
|
||||
}
|
||||
tr {height: 30px;}
|
||||
|
||||
textarea {
|
||||
resize: none;
|
||||
height:50px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div style="text-align: center;">
|
||||
<h1>Digital Clcok & Scrolling Text with ESP32 and P10 RGB 32x16</h1>
|
||||
</div>
|
||||
|
||||
<div class="div_Form">
|
||||
<form>
|
||||
<!-- Input Key -->
|
||||
<label for="keys_TXT">Key :</label>
|
||||
<input type="password" style="width: 170px;" id="input_Keys_TXT" name="input_Keys_TXT" maxlength="20" placeholder="Enter key here..." />
|
||||
<!-- -->
|
||||
|
||||
<hr style="border: 1px solid #e6e6e6;">
|
||||
|
||||
<!-- Displays and applies time and date. -->
|
||||
<label id="show_Date_Time">Please wait...</label>
|
||||
<br>
|
||||
<button type="button" class="myButton" style="font-size: 12px; padding: 3px 10px; margin-top: 5px;" id="btn_Apply_TimeDate" onclick="btn_Apply_TimeDate_Click()">Apply Time and Date</button>
|
||||
<!-- -->
|
||||
|
||||
<hr style="border: 1px solid #e6e6e6;">
|
||||
|
||||
|
||||
<table style="width:280px; margin-left: -1px;">
|
||||
<!-- Set display mode. -->
|
||||
<tr>
|
||||
<td>Display Mode</td>
|
||||
<td>:</td>
|
||||
<td>
|
||||
<select name="input_Display_Mode" id="input_Display_Mode">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
</select>
|
||||
</td>
|
||||
<td align="right">
|
||||
<button type="button" class="myButton" style="font-size: 12px; padding: 3px 10px;" id="btn_Apply_Display_Mode" onclick="btn_Apply_Display_Mode_Click()">Apply</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- -->
|
||||
|
||||
<!-- Set Brightness. -->
|
||||
<tr>
|
||||
<td>Brightness</td>
|
||||
<td>:</td>
|
||||
<td>
|
||||
<input type="text" value="50" id="input_Brightness" maxlength="3" size="3" oninput="this.value = this.value.replace(/[^0-9.]/g, '').replace(/(\..*?)\..*/g, '$1');" /> (0 - 255)
|
||||
</td>
|
||||
<td align="right">
|
||||
<button type="button" class="myButton" style="font-size: 12px; padding: 3px 10px;" id="btn_Apply_Input_Brightness" onclick="btn_Apply_Input_Brightness_Click()">Apply</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- -->
|
||||
|
||||
<!-- Set Clock Color. -->
|
||||
<tr>
|
||||
<td>Clock Color</td>
|
||||
<td>:</td>
|
||||
<td>
|
||||
<input type="color" id="input_Color_Clock" name="input_Color_Clock" value="#0000ff">
|
||||
</td>
|
||||
<td align="right">
|
||||
<button type="button" class="myButton" style="font-size: 12px; padding: 3px 10px;" id="btn_Apply_Input_Color_Clock" onclick="btn_Apply_Input_Color_Clock_Click()">Apply</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- -->
|
||||
|
||||
<!-- Set Date Color. -->
|
||||
<tr>
|
||||
<td>Date Color</td>
|
||||
<td>:</td>
|
||||
<td>
|
||||
<input type="color" id="input_Color_Date" name="input_Color_Date" value="#0000ff">
|
||||
</td>
|
||||
<td align="right">
|
||||
<button type="button" class="myButton" style="font-size: 12px; padding: 3px 10px;" id="btn_Apply_Input_Color_Date" onclick="btn_Apply_Input_Color_Date_Click()">Apply</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- -->
|
||||
</table>
|
||||
|
||||
<hr style="border: 1px solid #e6e6e6;">
|
||||
|
||||
<label for="Keys_TXT">Scrolling Text :</label>
|
||||
<br>
|
||||
<table style="width:100%; margin-left: -1px;">
|
||||
<tr>
|
||||
<!-- Set Scrolling Text. -->
|
||||
<td>
|
||||
<textarea id="input_Scrolling_Text" name="input_Scrolling_Text" style="width: 100%; margin: 0px; padding: 0px;" maxlength="150" placeholder="Enter text here...(Max 150 characters)"></textarea>
|
||||
</td>
|
||||
<td style="width: 5px;"></td>
|
||||
<td style="width: 30px; vertical-align: top;" align="center">
|
||||
<button type="button" class="myButton myButtonX" style="font-size: 12px; padding: 3px 10px;" id="btn_Clear_Input_Scrolling_Text" onclick="btn_Clear_Input_Scrolling_Text_Click()">X</button>
|
||||
</td>
|
||||
<td style="width: 50px; vertical-align: top;" align="right">
|
||||
<button type="button" class="myButton" style="font-size: 12px; padding: 3px 10px;" id="btn_Apply_Input_Scrolling_Text" onclick="btn_Apply_Input_Scrolling_Text_Click()">Apply</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- -->
|
||||
</table>
|
||||
|
||||
<br>
|
||||
|
||||
<table style="width:280px; margin-left: -1px;">
|
||||
<!-- Set Text Color. -->
|
||||
<tr>
|
||||
<td>Text Color</td>
|
||||
<td>:</td>
|
||||
<td>
|
||||
<input type="color" id="input_Text_Color" name="input_Text_Color" value="#0000ff">
|
||||
</td>
|
||||
<td align="right">
|
||||
<button type="button" class="myButton" style="font-size: 12px; padding: 3px 10px;" id="btn_Apply_Input_Text_Color" onclick="btn_Apply_Input_Text_Color_Click()">Apply</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- -->
|
||||
|
||||
<!-- Set Scrolling Speed. -->
|
||||
<tr>
|
||||
<td>Scrolling Speed</td>
|
||||
<td>:</td>
|
||||
<td>
|
||||
<select name="input_Scrolling_Speed" id="input_Scrolling_Speed">
|
||||
<option value="20">20</option>
|
||||
<option value="25">25</option>
|
||||
<option value="30">30</option>
|
||||
<option value="35">35</option>
|
||||
<option value="40">40</option>
|
||||
<option value="45">45</option>
|
||||
<option value="50">50</option>
|
||||
<option value="55">55</option>
|
||||
<option value="60">60</option>
|
||||
<option value="65">65</option>
|
||||
<option value="70">70</option>
|
||||
<option value="75">75</option>
|
||||
</select>
|
||||
</td>
|
||||
<td align="right">
|
||||
<button type="button" class="myButton" style="font-size: 12px; padding: 3px 10px;" id="btn_Apply_Input_Scrolling_Speed" onclick="btn_Apply_Input_Scrolling_Speed_Click()">Apply</button>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- -->
|
||||
</table>
|
||||
|
||||
<hr style="border: 1px solid #e6e6e6;">
|
||||
|
||||
<button type="button" class="myButton" id="btn_Get_Settings" onclick="btn_Get_Settings_Click()">Get Settings</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
setInterval(myTimer, 1000);
|
||||
|
||||
var t_Hour;
|
||||
var t_Minute;
|
||||
var t_Second;
|
||||
|
||||
const d_DaysOfTheWeek_Array = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
||||
|
||||
var d_DaysOfTheWeek_Now;
|
||||
var d_Day;
|
||||
var d_Month;
|
||||
var d_Year;
|
||||
|
||||
var full_DateTime;
|
||||
|
||||
//________________________________________________________________________________ myTimer()
|
||||
function myTimer() {
|
||||
getDateTime();
|
||||
document.getElementById("show_Date_Time").innerHTML = full_DateTime;
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ getDateTime()
|
||||
function getDateTime() {
|
||||
const dt = new Date();
|
||||
|
||||
t_Hour = dt.getHours();
|
||||
t_Minute = dt.getMinutes();;
|
||||
t_Second = dt.getSeconds();
|
||||
|
||||
d_DaysOfTheWeek_Now = dt.getDay();
|
||||
d_Day = dt.getDate();
|
||||
d_Month = dt.getMonth() + 1;
|
||||
d_Year = dt.getFullYear();
|
||||
|
||||
full_DateTime = "Date : <b>";
|
||||
full_DateTime += d_DaysOfTheWeek_Array[d_DaysOfTheWeek_Now];
|
||||
full_DateTime += ", ";
|
||||
full_DateTime += d_Day.toString().padStart(2, '0') + "-" + d_Month.toString().padStart(2, '0') + "-" + d_Year;
|
||||
full_DateTime += "</b> | Time : <b>" + t_Hour.toString().padStart(2, '0') + ":" + t_Minute.toString().padStart(2, '0') + ":" + t_Second.toString().padStart(2, '0') + "</b>";
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ check_Key_TXT()
|
||||
function check_Key_TXT() {
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
|
||||
if (key_TXT == "") {
|
||||
alert("Error ! \rThe key cannot be empty.");
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function btn_Apply_TimeDate_Click()
|
||||
// Function to send settings to the server.
|
||||
function btn_Apply_TimeDate_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
|
||||
getDateTime();
|
||||
|
||||
var msg;
|
||||
msg = "key=" + key_TXT;
|
||||
msg += "&sta=setTimeDate";
|
||||
msg += "&d_Year=" + d_Year;
|
||||
msg += "&d_Month=" + d_Month;
|
||||
msg += "&d_Day=" + d_Day;
|
||||
msg += "&t_Hour=" + t_Hour;
|
||||
msg += "&t_Minute=" + t_Minute;
|
||||
msg += "&t_Second=" + t_Second;
|
||||
|
||||
Send("set", msg);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function btn_Apply_Display_Mode_Click()
|
||||
// Function to send settings to the server.
|
||||
function btn_Apply_Display_Mode_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
var input_Display_Mode = document.getElementById("input_Display_Mode").value;
|
||||
|
||||
var msg;
|
||||
msg = "key=" + key_TXT;
|
||||
msg += "&sta=setDisplayMode";
|
||||
msg += "&input_Display_Mode=" + input_Display_Mode;
|
||||
|
||||
Send("set", msg);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function btn_Apply_Input_Brightness_Click()
|
||||
// Function to send settings to the server.
|
||||
function btn_Apply_Input_Brightness_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
var input_Brightness = document.getElementById("input_Brightness").value;
|
||||
|
||||
var msg;
|
||||
msg = "key=" + key_TXT;
|
||||
msg += "&sta=setBrightness";
|
||||
msg += "&input_Brightness=" + input_Brightness;
|
||||
|
||||
Send("set", msg);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function btn_Apply_Input_Color_Clock_Click()
|
||||
// Function to send settings to the server.
|
||||
function btn_Apply_Input_Color_Clock_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
var input_Color_Clock = hexToRgb(document.getElementById("input_Color_Clock").value);
|
||||
var Color_Clock_R = input_Color_Clock[0];
|
||||
var Color_Clock_G = input_Color_Clock[1];
|
||||
var Color_Clock_B = input_Color_Clock[2];
|
||||
|
||||
var msg;
|
||||
msg = "key=" + key_TXT;
|
||||
msg += "&sta=setColorClock";
|
||||
msg += "&Color_Clock_R=" + Color_Clock_R + "&Color_Clock_G=" + Color_Clock_G + "&Color_Clock_B=" + Color_Clock_B;
|
||||
|
||||
Send("set", msg);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function btn_Apply_Input_Color_Date_Click()
|
||||
// Function to send settings to the server.
|
||||
function btn_Apply_Input_Color_Date_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
var input_Color_Date = hexToRgb(document.getElementById("input_Color_Date").value);
|
||||
var Color_Date_R = input_Color_Date[0];
|
||||
var Color_Date_G = input_Color_Date[1];
|
||||
var Color_Date_B = input_Color_Date[2];
|
||||
|
||||
var msg;
|
||||
msg = "key=" + key_TXT;
|
||||
msg += "&sta=setColorDate";
|
||||
msg += "&Color_Date_R=" + Color_Date_R + "&Color_Date_G=" + Color_Date_G + "&Color_Date_B=" + Color_Date_B;
|
||||
|
||||
Send("set", msg);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ btn_Clear_Input_Scrolling_Text_Click()
|
||||
function btn_Clear_Input_Scrolling_Text_Click() {
|
||||
document.getElementById("input_Scrolling_Text").value = "";
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function btn_Apply_Input_Scrolling_Text_Click()
|
||||
// Function to send settings to the server.
|
||||
function btn_Apply_Input_Scrolling_Text_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
var input_Scrolling_Text = document.getElementById("input_Scrolling_Text").value;
|
||||
|
||||
var msg;
|
||||
msg = "key=" + key_TXT;
|
||||
msg += "&sta=setScrollingText";
|
||||
msg += "&input_Scrolling_Text=" + input_Scrolling_Text;
|
||||
|
||||
Send("set", msg);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function btn_Apply_Input_Text_Color_Click()
|
||||
// Function to send settings to the server.
|
||||
function btn_Apply_Input_Text_Color_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
var input_Text_Color = hexToRgb(document.getElementById("input_Text_Color").value);
|
||||
var Color_Text_R = input_Text_Color[0];
|
||||
var Color_Text_G = input_Text_Color[1];
|
||||
var Color_Text_B = input_Text_Color[2];
|
||||
|
||||
var msg;
|
||||
msg = "key=" + key_TXT;
|
||||
msg += "&sta=setTextColor";
|
||||
msg += "&Color_Text_R=" + Color_Text_R + "&Color_Text_G=" + Color_Text_G + "&Color_Text_B=" + Color_Text_B;
|
||||
|
||||
Send("set", msg);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function btn_Apply_Input_Scrolling_Speed_Click()
|
||||
// Function to send settings to the server.
|
||||
function btn_Apply_Input_Scrolling_Speed_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
var input_Scrolling_Speed = document.getElementById("input_Scrolling_Speed").value;
|
||||
|
||||
var msg;
|
||||
msg = "key=" + key_TXT;
|
||||
msg += "&sta=setScrollingSpeed";
|
||||
msg += "&input_Scrolling_Speed=" + input_Scrolling_Speed;
|
||||
|
||||
Send("set", msg);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ btn_Get_Settings_Click()
|
||||
function btn_Get_Settings_Click() {
|
||||
if (check_Key_TXT() == false) return;
|
||||
|
||||
var key_TXT = document.getElementById("input_Keys_TXT").value;
|
||||
|
||||
var send_Request;
|
||||
send_Request = "key=" + key_TXT;
|
||||
send_Request += "&sta=getSettings";
|
||||
|
||||
Send("get", send_Request);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function hexToRgb(hex)
|
||||
function hexToRgb(hex) {
|
||||
const normal = hex.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i);
|
||||
if (normal) return normal.slice(1).map(e => parseInt(e, 16));
|
||||
|
||||
const shorthand = hex.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i);
|
||||
if (shorthand) return shorthand.slice(1).map(e => 0x11 * parseInt(e, 16));
|
||||
|
||||
return null;
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ rgbToHex(red, green, blue)
|
||||
function rgbToHex(red, green, blue) {
|
||||
const rgb = (red << 16) | (green << 8) | (blue << 0);
|
||||
return '#' + (0x1000000 + rgb).toString(16).slice(1);
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function apply_the_Received_Settings(texts)
|
||||
// Function to apply settings received from the server.
|
||||
function apply_the_Received_Settings(texts) {
|
||||
const myArray_Getting_Settings = texts.split("|");
|
||||
|
||||
var input_Display_Mode = myArray_Getting_Settings[0];
|
||||
var input_Brightness = myArray_Getting_Settings[1];
|
||||
|
||||
var Color_Clock_R = myArray_Getting_Settings[2];
|
||||
var Color_Clock_G = myArray_Getting_Settings[3];
|
||||
var Color_Clock_B = myArray_Getting_Settings[4];
|
||||
var input_Color_Clock = rgbToHex(Color_Clock_R, Color_Clock_G, Color_Clock_B);
|
||||
|
||||
var Color_Date_R = myArray_Getting_Settings[5];
|
||||
var Color_Date_G = myArray_Getting_Settings[6];
|
||||
var Color_Date_B = myArray_Getting_Settings[7];
|
||||
var input_Color_Date = rgbToHex(Color_Date_R, Color_Date_G, Color_Date_B);
|
||||
|
||||
var input_Scrolling_Text = myArray_Getting_Settings[8];
|
||||
|
||||
var Color_Text_R = myArray_Getting_Settings[9];
|
||||
var Color_Text_G = myArray_Getting_Settings[10];
|
||||
var Color_Text_B = myArray_Getting_Settings[11];
|
||||
var input_Text_Color = rgbToHex(Color_Text_R, Color_Text_G, Color_Text_B);
|
||||
|
||||
var input_Scrolling_Speed = myArray_Getting_Settings[12];
|
||||
|
||||
|
||||
document.getElementById("input_Display_Mode").value = input_Display_Mode;
|
||||
document.getElementById("input_Brightness").value = input_Brightness;
|
||||
document.getElementById("input_Color_Clock").value = input_Color_Clock;
|
||||
document.getElementById("input_Color_Date").value = input_Color_Date;
|
||||
document.getElementById("input_Scrolling_Text").value = input_Scrolling_Text;
|
||||
document.getElementById("input_Text_Color").value = input_Text_Color;
|
||||
document.getElementById("input_Scrolling_Speed").value = input_Scrolling_Speed;
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
//________________________________________________________________________________ function Send(sta, msg)
|
||||
function Send(sta, msg) {
|
||||
if (window.XMLHttpRequest) {
|
||||
// code for IE7+, Firefox, Chrome, Opera, Safari
|
||||
xmlhttp = new XMLHttpRequest();
|
||||
} else {
|
||||
// code for IE6, IE5
|
||||
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
if (this.responseText == "+ERR") {
|
||||
alert("Error !\rWrong Key !\rPlease enter the correct key.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.responseText == "+ERR_DM") {
|
||||
alert("Error !\rThis setting is only for Display Mode : 1. \rPlease change the Display Mode to apply this setting.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sta == "get") {
|
||||
apply_the_Received_Settings(this.responseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlhttp.open("GET", "settings?" + msg, true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
# Guide de Démarrage Rapide - ESP32 P10 Digital Clock
|
||||
|
||||
## 🚀 Démarrage en 5 minutes
|
||||
|
||||
### Étape 1 : Préparation
|
||||
1. **Installez PlatformIO** dans VS Code
|
||||
2. **Ouvrez ce dossier** dans VS Code
|
||||
3. **Connectez votre ESP32** en USB
|
||||
|
||||
### Étape 2 : Configuration WiFi
|
||||
Modifiez dans `src/main.cpp` lignes ~100 :
|
||||
```cpp
|
||||
const char* ssid = "VOTRE_WIFI";
|
||||
const char* password = "VOTRE_MOT_DE_PASSE";
|
||||
```
|
||||
|
||||
### Étape 3 : Câblage (IMPORTANT !)
|
||||
|
||||
#### Panneau P10 → ESP32
|
||||
```
|
||||
HUB75 → ESP32
|
||||
R1 → GPIO2
|
||||
G1 → GPIO15
|
||||
B1 → GPIO4
|
||||
R2 → GPIO16
|
||||
G2 → GPIO17
|
||||
B2 → GPIO5
|
||||
A → GPIO19
|
||||
B → GPIO23
|
||||
C → GPIO18
|
||||
CLK → GPIO14
|
||||
STB → GPIO32
|
||||
OE → GPIO33
|
||||
GND → GND (plusieurs connexions)
|
||||
```
|
||||
|
||||
#### RTC DS3231 → ESP32
|
||||
```
|
||||
VCC → 3.3V
|
||||
GND → GND
|
||||
SDA → GPIO21
|
||||
SCL → GPIO22
|
||||
```
|
||||
|
||||
### Étape 4 : Test rapide
|
||||
1. **Test du panneau P10** :
|
||||
```bash
|
||||
pio run -e p10_test --target upload
|
||||
```
|
||||
|
||||
2. **Test du RTC** :
|
||||
```bash
|
||||
pio run -e rtc_test --target upload
|
||||
```
|
||||
|
||||
### Étape 5 : Projet principal
|
||||
```bash
|
||||
pio run -e main --target upload
|
||||
pio device monitor
|
||||
```
|
||||
|
||||
## 🌐 Configuration Web
|
||||
|
||||
1. **Trouvez l'IP** dans le moniteur série
|
||||
2. **Ouvrez votre navigateur** → http://IP_AFFICHEE
|
||||
3. **Utilisez la clé** : `p10rgbesp32ws`
|
||||
4. **Configurez** date, heure, couleurs, texte
|
||||
|
||||
## 🔧 Commandes Utiles
|
||||
|
||||
```bash
|
||||
# Compilation principale
|
||||
pio run -e main
|
||||
|
||||
# Upload et monitoring
|
||||
pio run -e main -t upload && pio device monitor
|
||||
|
||||
# Test des composants
|
||||
pio run -e rtc_test -t upload # Test RTC
|
||||
pio run -e p10_test -t upload # Test P10
|
||||
pio run -e nvs_erase -t upload # Reset mémoire
|
||||
|
||||
# Nettoyage
|
||||
pio run -t clean
|
||||
```
|
||||
|
||||
## ⚡ Commandes VS Code
|
||||
- **Ctrl+Shift+P** → "Tasks: Run Task"
|
||||
- Choisissez parmi :
|
||||
- PlatformIO: Build Main Project
|
||||
- PlatformIO: Upload Main Project
|
||||
- PlatformIO: Test RTC Module
|
||||
- PlatformIO: Test P10 Matrix
|
||||
- PlatformIO: Monitor Serial
|
||||
|
||||
## 🚨 Problèmes Courants
|
||||
|
||||
### L'affichage ne fonctionne pas
|
||||
- ✅ Vérifiez l'**alimentation 5V** (crucial !)
|
||||
- ✅ Vérifiez **toutes les connexions**
|
||||
- ✅ Testez avec `pio run -e p10_test -t upload`
|
||||
|
||||
### WiFi ne se connecte pas
|
||||
- ✅ Vérifiez SSID/mot de passe
|
||||
- ✅ L'ESP32 créera un point d'accès "ESP32_Clock"
|
||||
|
||||
### RTC ne fonctionne pas
|
||||
- ✅ Vérifiez connexions I2C (SDA/SCL)
|
||||
- ✅ Testez avec `pio run -e rtc_test -t upload`
|
||||
|
||||
### Paramètres perdus
|
||||
- ✅ Effacez la mémoire : `pio run -e nvs_erase -t upload`
|
||||
|
||||
## 📱 Interface Web - Fonctionnalités
|
||||
|
||||
- **Date/Heure** : Configuration complète
|
||||
- **Mode 1** : Couleurs manuelles (RGB)
|
||||
- **Mode 2** : Changement automatique de couleurs
|
||||
- **Luminosité** : 0-255
|
||||
- **Texte défilant** : Message personnalisé
|
||||
- **Vitesse** : Réglage du défilement
|
||||
|
||||
## 💡 Configuration Avancée
|
||||
|
||||
### Changement des pins
|
||||
Modifiez dans `src/main.cpp` :
|
||||
```cpp
|
||||
#define P_LAT 5 // Pin Latch
|
||||
#define P_A 19 // Pin A
|
||||
#define P_B 23 // Pin B
|
||||
#define P_C 18 // Pin C
|
||||
#define P_OE 4 // Pin Output Enable
|
||||
```
|
||||
|
||||
### Réduction du bruit d'affichage
|
||||
```cpp
|
||||
#define PxMATRIX_SPI_FREQUENCY 8000000 // Réduire si bruit
|
||||
```
|
||||
|
||||
## 📋 Checklist de Test
|
||||
|
||||
- [ ] ESP32 se connecte au WiFi
|
||||
- [ ] Interface web accessible
|
||||
- [ ] Heure s'affiche correctement
|
||||
- [ ] Date défile en bas
|
||||
- [ ] Texte personnalisé fonctionne
|
||||
- [ ] Changement de couleurs (mode 2)
|
||||
- [ ] Réglage luminosité
|
||||
- [ ] Sauvegarde des paramètres
|
||||
|
||||
## 🎯 Prêt à utiliser !
|
||||
|
||||
Une fois tout testé, votre horloge affichera :
|
||||
- **Heure** en haut (HH:MM avec : clignotant)
|
||||
- **Date et texte** défilant en bas
|
||||
- **Couleurs** selon le mode choisi
|
||||
- **Configuration** via navigateur web
|
||||
|
||||
Clé d'accès web : **p10rgbesp32ws**
|
||||
@@ -0,0 +1,245 @@
|
||||
# ESP32 P10 RGB 32x16 Digital Clock - PlatformIO Version
|
||||
|
||||
## Description
|
||||
|
||||
Horloge numérique utilisant un panneau P10 RGB 32x16 avec ESP32, module RTC DS3231 et interface web de configuration.
|
||||
|
||||
Version adaptée pour PlatformIO à partir du code Arduino IDE original.
|
||||
|
||||
## Matériel Requis
|
||||
|
||||
- **ESP32 DEVKIT V1**
|
||||
- **Panneau P10 RGB 32x16 HUB75** (Scan 1/8)
|
||||
- Référence utilisée : P10-2727-8S-32X16-A
|
||||
- ICs : RUC7258D, DP5125D, 74HC245KA
|
||||
- **Module RTC DS3231**
|
||||
- **Alimentation 5V** (importante pour le panneau P10)
|
||||
|
||||
## Brochage
|
||||
|
||||
### Connexions P10 HUB75
|
||||
```
|
||||
HUB75 Pin | ESP32 Pin
|
||||
----------|----------
|
||||
R1 | GPIO 2
|
||||
G1 | GPIO 15
|
||||
B1 | GPIO 4
|
||||
GND | GND
|
||||
R2 | GPIO 16
|
||||
G2 | GPIO 17
|
||||
B2 | GPIO 5
|
||||
GND | GND
|
||||
A | GPIO 19
|
||||
B | GPIO 23
|
||||
C | GPIO 18
|
||||
GND | GND
|
||||
CLK | GPIO 14
|
||||
STB | GPIO 32
|
||||
OE | GPIO 33
|
||||
GND | GND
|
||||
```
|
||||
|
||||
**Note :** Ces connexions peuvent varier selon votre panneau P10. Consultez le code et ajustez si nécessaire.
|
||||
|
||||
### Connexions RTC DS3231
|
||||
```
|
||||
DS3231 | ESP32
|
||||
-------|-------
|
||||
VCC | 3.3V
|
||||
GND | GND
|
||||
SDA | GPIO 21
|
||||
SCL | GPIO 22
|
||||
```
|
||||
|
||||
## Installation et Configuration
|
||||
|
||||
### 1. Installation PlatformIO
|
||||
|
||||
Si vous n'avez pas encore PlatformIO :
|
||||
```bash
|
||||
# Via VS Code
|
||||
# Installez l'extension PlatformIO IDE
|
||||
|
||||
# Via ligne de commande
|
||||
pip install platformio
|
||||
```
|
||||
|
||||
### 2. Configuration du projet
|
||||
|
||||
1. **Clonez ou téléchargez** ce projet
|
||||
2. **Ouvrez le dossier** dans VS Code avec PlatformIO
|
||||
3. **Modifiez les paramètres WiFi** dans `src/main.cpp` :
|
||||
|
||||
```cpp
|
||||
// Configuration WiFi - Modifiez selon vos besoins
|
||||
const char* ssid = "VOTRE_WIFI_SSID";
|
||||
const char* password = "VOTRE_MOT_DE_PASSE_WIFI";
|
||||
```
|
||||
|
||||
### 3. Compilation et téléversement
|
||||
|
||||
```bash
|
||||
# Compilation
|
||||
pio run
|
||||
|
||||
# Téléversement
|
||||
pio run --target upload
|
||||
|
||||
# Monitoring série
|
||||
pio device monitor
|
||||
```
|
||||
|
||||
Ou utilisez les boutons PlatformIO dans VS Code.
|
||||
|
||||
## Structure du Projet
|
||||
|
||||
```
|
||||
├── platformio.ini # Configuration PlatformIO
|
||||
├── src/
|
||||
│ └── main.cpp # Code principal de l'horloge
|
||||
├── include/
|
||||
│ └── PageIndex.h # Interface web HTML
|
||||
├── examples/
|
||||
│ ├── rtc_test.cpp # Test du module RTC
|
||||
│ ├── p10_test.cpp # Test du panneau P10
|
||||
│ └── nvs_erase.cpp # Effacement mémoire NVS
|
||||
└── README.md # Ce fichier
|
||||
```
|
||||
|
||||
## Utilisation
|
||||
|
||||
### Premier démarrage
|
||||
|
||||
1. **Téléversez le code** sur l'ESP32
|
||||
2. **Ouvrez le moniteur série** (115200 baud)
|
||||
3. L'ESP32 va essayer de se connecter à votre WiFi
|
||||
4. Si la connexion échoue, il créera un point d'accès WiFi
|
||||
|
||||
### Configuration via interface web
|
||||
|
||||
1. **Connectez-vous au réseau WiFi** :
|
||||
- Si connecté à votre WiFi : utilisez l'IP affichée dans le moniteur série
|
||||
- Sinon connectez-vous au point d'accès "ESP32_Clock" (mot de passe : "esp32clock")
|
||||
|
||||
2. **Ouvrez votre navigateur** et allez à l'adresse IP
|
||||
|
||||
3. **Utilisez la clé** : `p10rgbesp32ws`
|
||||
|
||||
4. **Configurez** :
|
||||
- Date et heure
|
||||
- Mode d'affichage (1 = couleurs manuelles, 2 = couleurs automatiques)
|
||||
- Luminosité (0-255)
|
||||
- Couleurs (en mode 1)
|
||||
- Texte défilant
|
||||
- Vitesse de défilement
|
||||
|
||||
### Configuration de l'heure RTC
|
||||
|
||||
Vous pouvez aussi configurer l'heure directement via le moniteur série :
|
||||
```
|
||||
SET,2024,8,1,14,30,0
|
||||
```
|
||||
Format : `SET,année,mois,jour,heure,minute,seconde`
|
||||
|
||||
## Programmes d'exemple
|
||||
|
||||
### Test du module RTC
|
||||
```bash
|
||||
# Modifiez src/main.cpp pour inclure examples/rtc_test.cpp
|
||||
# Ou créez un nouveau projet avec ce fichier
|
||||
```
|
||||
|
||||
### Test du panneau P10
|
||||
```bash
|
||||
# Modifiez src/main.cpp pour inclure examples/p10_test.cpp
|
||||
# Utile pour vérifier les connexions
|
||||
```
|
||||
|
||||
### Effacement mémoire NVS
|
||||
```bash
|
||||
# Utilisez examples/nvs_erase.cpp si vous voulez
|
||||
# réinitialiser toutes les préférences sauvegardées
|
||||
```
|
||||
|
||||
## Modes d'affichage
|
||||
|
||||
### Mode 1 - Couleurs manuelles
|
||||
- Couleurs fixes définissables via l'interface web
|
||||
- Couleur de l'horloge personnalisable
|
||||
- Couleur de la date personnalisable
|
||||
- Couleur du texte personnalisable
|
||||
|
||||
### Mode 2 - Couleurs automatiques
|
||||
- Changement automatique des couleurs
|
||||
- Cycle entre : Rouge, Vert, Bleu, Jaune, Cyan, Magenta, Blanc
|
||||
|
||||
## Paramètres configurables
|
||||
|
||||
- **Date et heure** : via interface web ou moniteur série
|
||||
- **Luminosité** : 0-255
|
||||
- **Mode d'affichage** : 1 ou 2
|
||||
- **Couleurs RGB** : 0-255 pour chaque composante (mode 1)
|
||||
- **Texte défilant** : jusqu'à 150 caractères
|
||||
- **Vitesse de défilement** : 10-100 (plus bas = plus rapide)
|
||||
|
||||
## Dépannage
|
||||
|
||||
### Problèmes d'affichage
|
||||
- Vérifiez l'alimentation 5V (importante !)
|
||||
- Vérifiez les connexions HUB75
|
||||
- Ajustez `PxMATRIX_SPI_FREQUENCY` si vous voyez du bruit
|
||||
|
||||
### Problèmes WiFi
|
||||
- Vérifiez le SSID et le mot de passe
|
||||
- L'ESP32 basculera en mode point d'accès si la connexion échoue
|
||||
|
||||
### Problèmes RTC
|
||||
- Vérifiez les connexions I2C (SDA/SCL)
|
||||
- Testez avec le programme `examples/rtc_test.cpp`
|
||||
|
||||
### Réinitialisation
|
||||
- Utilisez `examples/nvs_erase.cpp` pour effacer toutes les préférences
|
||||
|
||||
## Configuration avancée
|
||||
|
||||
### Modification de la fréquence SPI
|
||||
```cpp
|
||||
// Dans src/main.cpp, modifiez si vous avez du bruit sur l'affichage
|
||||
#define PxMATRIX_SPI_FREQUENCY 10000000 // Valeurs possibles: 20000000, 15000000, 10000000, 8000000
|
||||
```
|
||||
|
||||
### Modification des pins
|
||||
```cpp
|
||||
// Modifiez ces valeurs dans src/main.cpp si votre câblage est différent
|
||||
#define P_LAT 5
|
||||
#define P_A 19
|
||||
#define P_B 23
|
||||
#define P_C 18
|
||||
#define P_OE 4
|
||||
```
|
||||
|
||||
## Bibliothèques utilisées
|
||||
|
||||
- **PxMatrix** : Contrôle du panneau P10 RGB
|
||||
- **RTClib** : Interface avec le module DS3231
|
||||
- **Preferences** : Sauvegarde des paramètres dans la flash
|
||||
- **WiFi** : Connectivité réseau
|
||||
- **WebServer** : Interface web de configuration
|
||||
|
||||
## Support
|
||||
|
||||
Pour obtenir de l'aide :
|
||||
1. Vérifiez ce README
|
||||
2. Consultez les programmes d'exemple
|
||||
3. Vérifiez les connexions et l'alimentation
|
||||
4. Consultez la documentation des bibliothèques utilisées
|
||||
|
||||
## Crédit
|
||||
|
||||
Projet original adapté pour PlatformIO. Code source basé sur les exemples et tutoriels de la communauté ESP32/Arduino.
|
||||
|
||||
Bibliothèques utilisées :
|
||||
- PxMatrix par 2dom (Dominic Buchstaller)
|
||||
- RTClib par Adafruit
|
||||
- Adafruit GFX Library
|
||||
- Adafruit BusIO
|
||||
@@ -0,0 +1,214 @@
|
||||
# Schémas de Connexion - ESP32 P10 Digital Clock
|
||||
|
||||
## Vue d'ensemble du système
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ Alimentation │ │ ESP32 │ │ Panneau P10 │
|
||||
│ 5V │ │ DEVKIT V1 │ │ RGB 32x16 │
|
||||
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
|
||||
│ + ────────────────────│ VIN │ │ │
|
||||
│ - ────────────────────│ GND │ │ │
|
||||
└─────────────────┘ │ │ │ │
|
||||
│ │ │ │
|
||||
┌─────────────────┐ │ │ │ │
|
||||
│ RTC DS3231 │ │ │ │ │
|
||||
├─────────────────┤ │ │ │ │
|
||||
│ VCC ──────────────────│ 3.3V │ │ │
|
||||
│ GND ──────────────────│ GND │ │ │
|
||||
│ SDA ──────────────────│ GPIO21 │ │ │
|
||||
│ SCL ──────────────────│ GPIO22 │ │ │
|
||||
└─────────────────┘ │ │ │ │
|
||||
│ GPIO2 ─────────────────│ R1 │
|
||||
│ GPIO15 ─────────────────│ G1 │
|
||||
│ GPIO4 ─────────────────│ B1 │
|
||||
│ GPIO16 ─────────────────│ R2 │
|
||||
│ GPIO17 ─────────────────│ G2 │
|
||||
│ GPIO5 ─────────────────│ B2 │
|
||||
│ GPIO19 ─────────────────│ A │
|
||||
│ GPIO23 ─────────────────│ B │
|
||||
│ GPIO18 ─────────────────│ C │
|
||||
│ GPIO14 ─────────────────│ CLK │
|
||||
│ GPIO32 ─────────────────│ STB (LAT) │
|
||||
│ GPIO33 ─────────────────│ OE │
|
||||
│ GND ─────────────────│ GND (multiple) │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
## Connecteur HUB75 - Vue détaillée
|
||||
|
||||
```
|
||||
HUB75 Connector (Vue de face)
|
||||
┌─────────────────────────┐
|
||||
│ 1 2 3 4 5 6 7 8 │
|
||||
│ ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐│
|
||||
│ │R││G││B││ ││R││G││B││ ││
|
||||
│ │1││1││1││G││2││2││2││G││
|
||||
│ └─┘└─┘└─┘│N│└─┘└─┘└─┘│N││
|
||||
│ │D│ │D││
|
||||
│ └─┘ └─┘│
|
||||
├─────────────────────────┤
|
||||
│ 9 10 11 12 13 14 15 16 │
|
||||
│ ┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐┌─┐│
|
||||
│ │A││B││C││G││C││S││O││G││
|
||||
│ │ ││ ││ ││N││L││T││E││N││
|
||||
│ │ ││ ││ ││D││K││B││ ││D││
|
||||
│ └─┘└─┘└─┘└─┘└─┘└─┘└─┘└─┘│
|
||||
└─────────────────────────┘
|
||||
|
||||
Pin 1 (R1) → ESP32 GPIO2 Pin 9 (A) → ESP32 GPIO19
|
||||
Pin 2 (G1) → ESP32 GPIO15 Pin 10 (B) → ESP32 GPIO23
|
||||
Pin 3 (B1) → ESP32 GPIO4 Pin 11 (C) → ESP32 GPIO18
|
||||
Pin 4 (GND) → ESP32 GND Pin 12 (GND) → ESP32 GND
|
||||
Pin 5 (R2) → ESP32 GPIO16 Pin 13 (CLK) → ESP32 GPIO14
|
||||
Pin 6 (G2) → ESP32 GPIO17 Pin 14 (STB) → ESP32 GPIO32
|
||||
Pin 7 (B2) → ESP32 GPIO5 Pin 15 (OE) → ESP32 GPIO33
|
||||
Pin 8 (GND) → ESP32 GND Pin 16 (GND) → ESP32 GND
|
||||
```
|
||||
|
||||
## ESP32 DEVKIT V1 - Pinout
|
||||
|
||||
```
|
||||
ESP32 DEVKIT V1
|
||||
┌─────────────────────────┐
|
||||
│ │
|
||||
│ ● ● │
|
||||
3.3V │ [ ] [ ] │ VIN ──── Alimentation 5V+
|
||||
GND │ [ ] [ ] │ GND ──── Alimentation 5V-
|
||||
Touch │ [ ] [ ] │ GPIO13
|
||||
Touch │ [ ] [ ] │ GPIO12
|
||||
Touch │ [ ] [ ] │ GPIO14 ──── CLK (P10)
|
||||
Touch │ [ ] [ ] │ GPIO27
|
||||
│ [ ] [ ] │ GPIO26
|
||||
│ [ ] [ ] │ GPIO25
|
||||
│ [ ] [ ] │ GPIO33 ──── OE (P10)
|
||||
│ [ ] [ ] │ GPIO32 ──── STB (P10)
|
||||
│ [ ] [ ] │ GPIO35
|
||||
│ [ ] [ ] │ GPIO34
|
||||
│ [ ] [ ] │ GPIO39
|
||||
│ [ ] [ ] │ GPIO36
|
||||
EN │ [ ] [ ] │ GPIO23 ──── B (P10)
|
||||
│ [ ] [ ] │ GPIO22 ──── SCL (RTC)
|
||||
GPIO2 ──│ [ ] [ ] │ GPIO21 ──── SDA (RTC)
|
||||
GPIO4 ──│ [ ] [ ] │ GPIO19 ──── A (P10)
|
||||
GPIO16 ──│ [ ] [ ] │ GPIO18 ──── C (P10)
|
||||
GPIO17 ──│ [ ] [ ] │ GPIO5 ──── B2 (P10)
|
||||
GPIO5 ──│ [ ] [ ] │ TX
|
||||
GPIO15 ──│ [ ] [ ] │ RX
|
||||
│ │
|
||||
│ ┌─────────────┐ │
|
||||
│ │ ESP32 │ │
|
||||
│ │ WiFi │ │
|
||||
│ │ Bluetooth │ │
|
||||
│ └─────────────┘ │
|
||||
│ │
|
||||
│ USB ┌─────────────┐ │
|
||||
│ ──── │ │ │
|
||||
└──────┴─────────────┴───┘
|
||||
|
||||
Connexions P10:
|
||||
GPIO2 → R1 GPIO19 → A
|
||||
GPIO15 → G1 GPIO23 → B
|
||||
GPIO4 → B1 GPIO18 → C
|
||||
GPIO16 → R2 GPIO14 → CLK
|
||||
GPIO17 → G2 GPIO32 → STB
|
||||
GPIO5 → B2 GPIO33 → OE
|
||||
|
||||
Connexions RTC:
|
||||
GPIO21 → SDA 3.3V → VCC
|
||||
GPIO22 → SCL GND → GND
|
||||
```
|
||||
|
||||
## Module RTC DS3231
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ RTC DS3231 │
|
||||
├─────────────────┤
|
||||
│ VCC ── 3.3V │ ──── ESP32 3.3V
|
||||
│ GND ── GND │ ──── ESP32 GND
|
||||
│ SCL ── Clock │ ──── ESP32 GPIO22
|
||||
│ SDA ── Data │ ──── ESP32 GPIO21
|
||||
└─────────────────┘
|
||||
|
||||
Note: Certains modules ont aussi:
|
||||
- 32K (sortie 32kHz) - Non utilisé
|
||||
- SQW (signal carré) - Non utilisé
|
||||
- RST (reset) - Non utilisé
|
||||
```
|
||||
|
||||
## Alimentation - IMPORTANT !
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Alimentation │ │ ESP32 │
|
||||
│ 5V/3A │ │ (via USB ou │
|
||||
│ │ │ pin VIN) │
|
||||
├─────────────────┤ ├─────────────────┤
|
||||
│ +5V ────────────┼─┬───┼── VIN │
|
||||
│ GND ────────────┼─┼───┼── GND │
|
||||
└─────────────────┘ │ └─────────────────┘
|
||||
│
|
||||
│ ┌─────────────────┐
|
||||
│ │ Panneau P10 │
|
||||
│ │ RGB 32x16 │
|
||||
│ ├─────────────────┤
|
||||
└───┼── +5V │
|
||||
│ (via HUB75) │
|
||||
└─────────────────┘
|
||||
|
||||
ATTENTION:
|
||||
- Le panneau P10 nécessite du 5V avec suffisamment de courant
|
||||
- Utilisez une alimentation 5V/3A minimum
|
||||
- L'ESP32 peut être alimenté via USB pour les tests
|
||||
- Pour un fonctionnement permanent, alimentez l'ESP32 via VIN avec du 5V
|
||||
```
|
||||
|
||||
## Câblage recommandé
|
||||
|
||||
```
|
||||
Étape 1: Connexions d'alimentation
|
||||
ESP32 VIN ← 5V+
|
||||
ESP32 GND ← 5V-
|
||||
P10 +5V ← 5V+ (via HUB75)
|
||||
P10 GND ← 5V- (via HUB75, plusieurs pins)
|
||||
|
||||
Étape 2: Connexions I2C (RTC)
|
||||
ESP32 GPIO21 ← RTC SDA
|
||||
ESP32 GPIO22 ← RTC SCL
|
||||
ESP32 3.3V ← RTC VCC
|
||||
ESP32 GND ← RTC GND
|
||||
|
||||
Étape 3: Connexions HUB75 (P10)
|
||||
ESP32 GPIO2 ← P10 R1
|
||||
ESP32 GPIO15 ← P10 G1
|
||||
ESP32 GPIO4 ← P10 B1
|
||||
ESP32 GPIO16 ← P10 R2
|
||||
ESP32 GPIO17 ← P10 G2
|
||||
ESP32 GPIO5 ← P10 B2
|
||||
ESP32 GPIO19 ← P10 A
|
||||
ESP32 GPIO23 ← P10 B
|
||||
ESP32 GPIO18 ← P10 C
|
||||
ESP32 GPIO14 ← P10 CLK
|
||||
ESP32 GPIO32 ← P10 STB/LAT
|
||||
ESP32 GPIO33 ← P10 OE
|
||||
ESP32 GND ← P10 GND (plusieurs connexions)
|
||||
```
|
||||
|
||||
## Vérification des connexions
|
||||
|
||||
Utilisez un multimètre pour vérifier :
|
||||
1. **Continuité** entre ESP32 et P10 pour chaque signal
|
||||
2. **Absence de court-circuit** entre VCC et GND
|
||||
3. **Tension 5V** sur les pins d'alimentation du P10
|
||||
4. **Tension 3.3V** sur le module RTC
|
||||
|
||||
## Troubleshooting connexions
|
||||
|
||||
| Problème | Vérification |
|
||||
|----------|-------------|
|
||||
| Affichage noir | Alimentation 5V, connexion OE |
|
||||
| Couleurs incorrectes | Connexions R1,G1,B1,R2,G2,B2 |
|
||||
| Affichage instable | Connexions CLK, STB, GND |
|
||||
| Position incorrecte | Connexions A, B, C |
|
||||
| RTC ne fonctionne pas | Connexions SDA, SCL, alimentation 3.3V |
|
||||
@@ -0,0 +1,293 @@
|
||||
/**
|
||||
* ESP32 P10 RGB Cascade Test
|
||||
* Test pour vérifier le bon fonctionnement des panneaux P10 en cascade
|
||||
*
|
||||
* Ce test affiche :
|
||||
* - Des bordures pour vérifier l'alignement des panneaux
|
||||
* - La numérotation de chaque panneau
|
||||
* - Des tests de couleurs
|
||||
* - Un texte défilant sur toute la largeur
|
||||
*
|
||||
* Compatible avec toutes les configurations de cascade définies dans platformio.ini
|
||||
*/
|
||||
|
||||
#define PxMATRIX_SPI_FREQUENCY 10000000
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <PxMatrix.h>
|
||||
|
||||
// Pins pour la matrice LED
|
||||
#define P_LAT 5
|
||||
#define P_A 19
|
||||
#define P_B 23
|
||||
#define P_C 18
|
||||
#define P_OE 4
|
||||
|
||||
// Configuration des panneaux - définie par les build flags
|
||||
#ifndef MATRIX_WIDTH
|
||||
#define MATRIX_WIDTH 32
|
||||
#endif
|
||||
|
||||
#ifndef MATRIX_HEIGHT
|
||||
#define MATRIX_HEIGHT 16
|
||||
#endif
|
||||
|
||||
#ifndef MATRIX_PANELS_X
|
||||
#define MATRIX_PANELS_X 1
|
||||
#endif
|
||||
|
||||
#ifndef MATRIX_PANELS_Y
|
||||
#define MATRIX_PANELS_Y 1
|
||||
#endif
|
||||
|
||||
// Calcul des dimensions totales
|
||||
#define TOTAL_WIDTH (MATRIX_WIDTH * MATRIX_PANELS_X)
|
||||
#define TOTAL_HEIGHT (MATRIX_HEIGHT * MATRIX_PANELS_Y)
|
||||
|
||||
// Configuration du timer
|
||||
hw_timer_t * timer = NULL;
|
||||
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
// Temps d'affichage ajusté selon le nombre de panneaux
|
||||
uint8_t display_draw_time = (MATRIX_PANELS_X * MATRIX_PANELS_Y > 4) ? 20 : 30;
|
||||
|
||||
// Objet matrice
|
||||
PxMATRIX display(TOTAL_WIDTH, TOTAL_HEIGHT, P_LAT, P_OE, P_A, P_B, P_C);
|
||||
|
||||
// Couleurs prédéfinies
|
||||
uint16_t myRED = display.color565(255, 0, 0);
|
||||
uint16_t myGREEN = display.color565(0, 255, 0);
|
||||
uint16_t myBLUE = display.color565(0, 0, 255);
|
||||
uint16_t myYELLOW = display.color565(255, 255, 0);
|
||||
uint16_t myCYAN = display.color565(0, 255, 255);
|
||||
uint16_t myMAGENTA = display.color565(255, 0, 255);
|
||||
uint16_t myWHITE = display.color565(255, 255, 255);
|
||||
uint16_t myBLACK = display.color565(0, 0, 0);
|
||||
uint16_t myORANGE = display.color565(255, 165, 0);
|
||||
|
||||
uint16_t colors[] = {myRED, myGREEN, myBLUE, myYELLOW, myCYAN, myMAGENTA, myWHITE, myORANGE};
|
||||
int numColors = sizeof(colors) / sizeof(colors[0]);
|
||||
|
||||
// Variables pour le texte défilant
|
||||
long scrollX = TOTAL_WIDTH;
|
||||
unsigned long lastScrollTime = 0;
|
||||
int scrollSpeed = 50;
|
||||
const char* scrollText = "=== CASCADE TEST - ESP32 P10 RGB PANELS ===";
|
||||
|
||||
// Gestionnaire d'interruption pour l'affichage
|
||||
void IRAM_ATTR display_updater() {
|
||||
portENTER_CRITICAL_ISR(&timerMux);
|
||||
display.display(display_draw_time);
|
||||
portEXIT_CRITICAL_ISR(&timerMux);
|
||||
}
|
||||
|
||||
// Activation du timer d'affichage
|
||||
void display_update_enable() {
|
||||
timer = timerBegin(0, 80, true);
|
||||
timerAttachInterrupt(timer, &display_updater, true);
|
||||
timerAlarmWrite(timer, 1500, true);
|
||||
timerAlarmEnable(timer);
|
||||
}
|
||||
|
||||
// Test des bordures et alignement des panneaux
|
||||
void testPanelAlignment() {
|
||||
Serial.println("Testing panel alignment...");
|
||||
|
||||
display.clearDisplay();
|
||||
|
||||
// Bordure extérieure
|
||||
display.drawRect(0, 0, TOTAL_WIDTH, TOTAL_HEIGHT, myWHITE);
|
||||
|
||||
// Lignes de séparation entre panneaux horizontaux
|
||||
for (int i = 1; i < MATRIX_PANELS_X; i++) {
|
||||
int x = i * MATRIX_WIDTH;
|
||||
display.drawLine(x, 0, x, TOTAL_HEIGHT - 1, myRED);
|
||||
}
|
||||
|
||||
// Lignes de séparation entre panneaux verticaux
|
||||
for (int i = 1; i < MATRIX_PANELS_Y; i++) {
|
||||
int y = i * MATRIX_HEIGHT;
|
||||
display.drawLine(0, y, TOTAL_WIDTH - 1, y, myGREEN);
|
||||
}
|
||||
|
||||
delay(3000);
|
||||
}
|
||||
|
||||
// Test de numérotation des panneaux
|
||||
void testPanelNumbering() {
|
||||
Serial.println("Testing panel numbering...");
|
||||
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
|
||||
for (int py = 0; py < MATRIX_PANELS_Y; py++) {
|
||||
for (int px = 0; px < MATRIX_PANELS_X; px++) {
|
||||
int panelNum = py * MATRIX_PANELS_X + px + 1;
|
||||
uint16_t color = colors[panelNum % numColors];
|
||||
|
||||
// Position au centre de chaque panneau
|
||||
int centerX = px * MATRIX_WIDTH + 2;
|
||||
int centerY = py * MATRIX_HEIGHT + 2;
|
||||
|
||||
// Fond coloré pour le panneau
|
||||
display.fillRect(px * MATRIX_WIDTH + 1, py * MATRIX_HEIGHT + 1,
|
||||
MATRIX_WIDTH - 2, MATRIX_HEIGHT - 2, color);
|
||||
|
||||
// Numéro du panneau en noir
|
||||
display.setTextColor(myBLACK);
|
||||
display.setCursor(centerX, centerY);
|
||||
display.print("P");
|
||||
display.setCursor(centerX, centerY + 8);
|
||||
display.print(panelNum);
|
||||
|
||||
delay(800);
|
||||
}
|
||||
}
|
||||
|
||||
delay(3000);
|
||||
}
|
||||
|
||||
// Test des couleurs sur tous les panneaux
|
||||
void testColors() {
|
||||
Serial.println("Testing colors...");
|
||||
|
||||
for (int i = 0; i < numColors; i++) {
|
||||
display.fillScreen(colors[i]);
|
||||
delay(800);
|
||||
}
|
||||
|
||||
display.clearDisplay();
|
||||
delay(500);
|
||||
}
|
||||
|
||||
// Test du texte défilant
|
||||
void testScrollingText() {
|
||||
Serial.println("Testing scrolling text...");
|
||||
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(myWHITE);
|
||||
|
||||
// Calculer la largeur approximative du texte
|
||||
int textWidth = strlen(scrollText) * 6;
|
||||
|
||||
// Faire défiler le texte 2 fois
|
||||
for (int cycle = 0; cycle < 2; cycle++) {
|
||||
scrollX = TOTAL_WIDTH;
|
||||
|
||||
while (scrollX > -textWidth) {
|
||||
unsigned long currentTime = millis();
|
||||
if (currentTime - lastScrollTime >= scrollSpeed) {
|
||||
lastScrollTime = currentTime;
|
||||
|
||||
// Effacer la ligne de texte
|
||||
display.fillRect(0, 8, TOTAL_WIDTH, 8, myBLACK);
|
||||
|
||||
// Afficher le texte à la nouvelle position
|
||||
display.setCursor(scrollX, 8);
|
||||
display.print(scrollText);
|
||||
|
||||
scrollX--;
|
||||
}
|
||||
|
||||
delay(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
delay(1000);
|
||||
Serial.println("\n=== ESP32 P10 RGB CASCADE TEST ===");
|
||||
Serial.printf("Configuration: %dx%d panels (%dx%d total resolution)\n",
|
||||
MATRIX_PANELS_X, MATRIX_PANELS_Y, TOTAL_WIDTH, TOTAL_HEIGHT);
|
||||
Serial.printf("Draw time: %d\n", display_draw_time);
|
||||
|
||||
// Initialisation de l'affichage
|
||||
display.begin(8);
|
||||
display_update_enable();
|
||||
display.clearDisplay();
|
||||
|
||||
// Luminosité adaptée au nombre de panneaux
|
||||
int brightness = 150;
|
||||
if (MATRIX_PANELS_X > 2) brightness = 100;
|
||||
if (MATRIX_PANELS_X > 4) brightness = 80;
|
||||
if (MATRIX_PANELS_X > 6) brightness = 60;
|
||||
|
||||
display.setBrightness(brightness);
|
||||
Serial.printf("Brightness set to: %d\n", brightness);
|
||||
|
||||
display.setTextWrap(false);
|
||||
display.setRotation(0);
|
||||
|
||||
// Message de démarrage
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(myWHITE);
|
||||
|
||||
// Calculer position centrée
|
||||
String startMsg = "CASCADE TEST";
|
||||
int msgWidth = startMsg.length() * 6;
|
||||
int startX = (TOTAL_WIDTH - msgWidth) / 2;
|
||||
if (startX < 0) startX = 0;
|
||||
|
||||
display.setCursor(startX, 0);
|
||||
display.print(startMsg);
|
||||
|
||||
if (TOTAL_HEIGHT > 8) {
|
||||
String configMsg = String(MATRIX_PANELS_X) + "x" + String(MATRIX_PANELS_Y) + " PANELS";
|
||||
int configWidth = configMsg.length() * 6;
|
||||
int configX = (TOTAL_WIDTH - configWidth) / 2;
|
||||
if (configX < 0) configX = 0;
|
||||
|
||||
display.setCursor(configX, 8);
|
||||
display.print(configMsg);
|
||||
}
|
||||
|
||||
delay(3000);
|
||||
|
||||
Serial.println("Starting cascade tests...");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Séquence de tests
|
||||
|
||||
Serial.println("\n--- Test Cycle Starting ---");
|
||||
|
||||
// 1. Test d'alignement des panneaux
|
||||
testPanelAlignment();
|
||||
|
||||
// 2. Test de numérotation des panneaux
|
||||
testPanelNumbering();
|
||||
|
||||
// 3. Test des couleurs
|
||||
testColors();
|
||||
|
||||
// 4. Test du texte défilant
|
||||
testScrollingText();
|
||||
|
||||
// Message de fin de cycle
|
||||
display.clearDisplay();
|
||||
display.setTextColor(myGREEN);
|
||||
|
||||
String okMsg = "TESTS OK";
|
||||
int okWidth = okMsg.length() * 6;
|
||||
int okX = (TOTAL_WIDTH - okWidth) / 2;
|
||||
if (okX < 0) okX = 0;
|
||||
|
||||
display.setCursor(okX, 0);
|
||||
display.print(okMsg);
|
||||
|
||||
if (TOTAL_HEIGHT > 8) {
|
||||
String restartMsg = "RESTARTING...";
|
||||
int restartWidth = restartMsg.length() * 6;
|
||||
int restartX = (TOTAL_WIDTH - restartWidth) / 2;
|
||||
if (restartX < 0) restartX = 0;
|
||||
|
||||
display.setCursor(restartX, 8);
|
||||
display.print(restartMsg);
|
||||
}
|
||||
|
||||
Serial.println("--- Test Cycle Completed ---");
|
||||
Serial.println("Restarting in 5 seconds...\n");
|
||||
delay(5000);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Effacement et reformatage de la mémoire NVS
|
||||
* Utilisez ce programme si vous voulez réinitialiser la mémoire de préférences
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <nvs_flash.h>
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
delay(1000);
|
||||
|
||||
Serial.println("=== NVS Memory Erase Tool ===");
|
||||
Serial.println("Erasing the NVS partition...");
|
||||
nvs_flash_erase(); // Effacer la partition NVS
|
||||
|
||||
Serial.println("Initializing the NVS partition...");
|
||||
nvs_flash_init(); // Initialiser la partition NVS
|
||||
|
||||
Serial.println("NVS Memory erase completed successfully.");
|
||||
Serial.println("You can now upload your main program.");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
delay(10);
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Test de la matrice P10 RGB 32x16
|
||||
* Ce programme permet de tester l'affichage sur la matrice P10
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <PxMatrix.h>
|
||||
|
||||
// Configuration SPI
|
||||
#define PxMATRIX_SPI_FREQUENCY 10000000
|
||||
|
||||
// Pins pour la matrice LED
|
||||
#define P_LAT 5
|
||||
#define P_A 19
|
||||
#define P_B 23
|
||||
#define P_C 18
|
||||
#define P_OE 4
|
||||
|
||||
// Dimensions de la matrice
|
||||
#define MATRIX_WIDTH 32
|
||||
#define MATRIX_HEIGHT 16
|
||||
|
||||
// Configuration du timer
|
||||
hw_timer_t * timer = NULL;
|
||||
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
// Temps d'affichage
|
||||
uint8_t display_draw_time = 30;
|
||||
|
||||
// Objet matrice
|
||||
PxMATRIX display(MATRIX_WIDTH, MATRIX_HEIGHT, P_LAT, P_OE, P_A, P_B, P_C);
|
||||
|
||||
// Couleurs
|
||||
uint16_t myRED = display.color565(255, 0, 0);
|
||||
uint16_t myGREEN = display.color565(0, 255, 0);
|
||||
uint16_t myBLUE = display.color565(0, 0, 255);
|
||||
uint16_t myYELLOW = display.color565(255, 255, 0);
|
||||
uint16_t myCYAN = display.color565(0, 255, 255);
|
||||
uint16_t myFUCHSIA = display.color565(255, 0, 255);
|
||||
uint16_t myWHITE = display.color565(255, 255, 255);
|
||||
uint16_t myBLACK = display.color565(0, 0, 0);
|
||||
|
||||
uint16_t myCOLOR_ARRAY[4] = {myRED, myGREEN, myBLUE, myWHITE};
|
||||
|
||||
// Gestionnaire d'interruption pour l'affichage
|
||||
void IRAM_ATTR display_updater() {
|
||||
portENTER_CRITICAL_ISR(&timerMux);
|
||||
display.display(display_draw_time);
|
||||
portEXIT_CRITICAL_ISR(&timerMux);
|
||||
}
|
||||
|
||||
// Activation/désactivation du timer d'affichage
|
||||
void display_update_enable(bool is_enable) {
|
||||
if (is_enable) {
|
||||
timer = timerBegin(0, 80, true);
|
||||
timerAttachInterrupt(timer, &display_updater, true);
|
||||
timerAlarmWrite(timer, 1500, true);
|
||||
timerAlarmEnable(timer);
|
||||
} else {
|
||||
timerDetachInterrupt(timer);
|
||||
timerAlarmDisable(timer);
|
||||
}
|
||||
}
|
||||
|
||||
void setup() {
|
||||
delay(2000);
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println("=== Test P10 RGB 32x16 Matrix ===");
|
||||
|
||||
// Initialisation de l'affichage
|
||||
display.begin(8); // Valeur 8 pour un panneau 1/8 scan
|
||||
delay(100);
|
||||
|
||||
// Activation des interruptions timer
|
||||
display_update_enable(true);
|
||||
delay(100);
|
||||
|
||||
display.clearDisplay();
|
||||
delay(1000);
|
||||
|
||||
display.setBrightness(125); // 0-255
|
||||
delay(100);
|
||||
|
||||
// Test des couleurs pleines
|
||||
Serial.println("Testing full screen colors...");
|
||||
display.fillScreen(myRED);
|
||||
delay(1000);
|
||||
display.fillScreen(myGREEN);
|
||||
delay(1000);
|
||||
display.fillScreen(myBLUE);
|
||||
delay(1000);
|
||||
display.fillScreen(myWHITE);
|
||||
delay(1000);
|
||||
|
||||
display.clearDisplay();
|
||||
delay(1000);
|
||||
|
||||
display.setTextWrap(false);
|
||||
display.setTextSize(1);
|
||||
display.setRotation(0);
|
||||
delay(100);
|
||||
|
||||
// Test d'affichage de texte
|
||||
Serial.println("Testing text display...");
|
||||
display.fillScreen(myRED);
|
||||
display.setTextColor(myWHITE);
|
||||
display.setCursor(0, 0);
|
||||
display.print("TEST");
|
||||
display.setCursor(15, 9);
|
||||
display.print("P10");
|
||||
delay(2500);
|
||||
|
||||
display.clearDisplay();
|
||||
delay(1000);
|
||||
|
||||
Serial.println("Setup completed. Starting color loop...");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
int myCOLOR_ARRAY_Length = sizeof(myCOLOR_ARRAY) / sizeof(myCOLOR_ARRAY[0]);
|
||||
|
||||
for (byte i = 0; i < myCOLOR_ARRAY_Length; i++) {
|
||||
// Test position 1
|
||||
display.setTextColor(myCOLOR_ARRAY[i]);
|
||||
display.setCursor(0, 0);
|
||||
display.print("1234");
|
||||
display.setCursor(0, 9);
|
||||
display.print("ABCD");
|
||||
delay(2500);
|
||||
|
||||
display.clearDisplay();
|
||||
delay(1000);
|
||||
|
||||
// Test position 2
|
||||
display.setTextColor(myCOLOR_ARRAY[i]);
|
||||
display.setCursor(4, 0);
|
||||
display.print("1234");
|
||||
display.setCursor(4, 9);
|
||||
display.print("ABCD");
|
||||
delay(2500);
|
||||
|
||||
display.clearDisplay();
|
||||
delay(1000);
|
||||
|
||||
// Test position 3
|
||||
display.setCursor(9, 0);
|
||||
display.print("1234");
|
||||
display.setCursor(9, 9);
|
||||
display.print("ABCD");
|
||||
delay(2500);
|
||||
|
||||
display.clearDisplay();
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
/**
|
||||
* Test du module RTC DS3231
|
||||
* Ce programme permet de tester et configurer le module RTC
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <RTClib.h>
|
||||
|
||||
RTC_DS3231 rtc;
|
||||
|
||||
char daysOfTheWeek[8][10] = {"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "ERROR"};
|
||||
|
||||
String inputString = "";
|
||||
bool stringComplete = false;
|
||||
|
||||
int d_year;
|
||||
byte d_month, d_day, daysOfTheWeek_Val;
|
||||
byte t_hour, t_minute, t_second;
|
||||
|
||||
unsigned long prevMill_Update_DateTime = 0;
|
||||
const long interval_Update_DateTime = 1000;
|
||||
|
||||
// Fonction pour traiter les données reçues
|
||||
String getValue(String data, char separator, int index) {
|
||||
int found = 0;
|
||||
int strIndex[] = { 0, -1 };
|
||||
int maxIndex = data.length() - 1;
|
||||
|
||||
for (int i = 0; i <= maxIndex && found <= index; i++) {
|
||||
if (data.charAt(i) == separator || i == maxIndex) {
|
||||
found++;
|
||||
strIndex[0] = strIndex[1] + 1;
|
||||
strIndex[1] = (i == maxIndex) ? i+1 : i;
|
||||
}
|
||||
}
|
||||
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
|
||||
}
|
||||
|
||||
// Gestion des événements série
|
||||
void serialEvent() {
|
||||
while (Serial.available()) {
|
||||
char inChar = (char)Serial.read();
|
||||
if (inChar == '\n') {
|
||||
stringComplete = true;
|
||||
return;
|
||||
}
|
||||
inputString += inChar;
|
||||
}
|
||||
}
|
||||
|
||||
// Récupération date/heure
|
||||
void get_DateTime() {
|
||||
DateTime now = rtc.now();
|
||||
|
||||
d_year = now.year();
|
||||
d_month = now.month();
|
||||
d_day = now.day();
|
||||
daysOfTheWeek_Val = now.dayOfTheWeek();
|
||||
if (daysOfTheWeek_Val > 7 || daysOfTheWeek_Val < 0) daysOfTheWeek_Val = 7;
|
||||
t_hour = now.hour();
|
||||
t_minute = now.minute();
|
||||
t_second = now.second();
|
||||
|
||||
char full_DateTime[60];
|
||||
sprintf(full_DateTime, "%s | %02d-%02d-%d | %02d:%02d:%02d",
|
||||
daysOfTheWeek[daysOfTheWeek_Val], d_day, d_month, d_year, t_hour, t_minute, t_second);
|
||||
|
||||
Serial.print("Date Time : ");
|
||||
Serial.println(full_DateTime);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
delay(2000);
|
||||
Serial.begin(115200);
|
||||
inputString.reserve(200);
|
||||
|
||||
Serial.println();
|
||||
Serial.println("------------");
|
||||
Serial.println("Starting the DS3231 RTC module.");
|
||||
if (!rtc.begin()) {
|
||||
Serial.println("Couldn't find RTC");
|
||||
while (1);
|
||||
}
|
||||
Serial.println("Successfully started the DS3231 RTC module.");
|
||||
Serial.println("------------");
|
||||
Serial.println();
|
||||
|
||||
Serial.println();
|
||||
Serial.println("------------");
|
||||
Serial.println("Serial monitor settings :");
|
||||
Serial.println("- End Char : Newline");
|
||||
Serial.println("- Baud Rate : 115200");
|
||||
Serial.println("------------");
|
||||
Serial.println();
|
||||
|
||||
Serial.println();
|
||||
Serial.println("------------");
|
||||
Serial.println("Example command to set the time and date on the RTC module : ");
|
||||
Serial.println("SET,2024,8,1,12,30,0");
|
||||
Serial.println();
|
||||
Serial.println("SET = command to set.");
|
||||
Serial.println("2024 = Year.");
|
||||
Serial.println("8 = Month.");
|
||||
Serial.println("1 = Day.");
|
||||
Serial.println("12 = Hour.");
|
||||
Serial.println("30 = Minute.");
|
||||
Serial.println("0 = Second.");
|
||||
Serial.println("------------");
|
||||
Serial.println();
|
||||
|
||||
delay(3000);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
serialEvent();
|
||||
|
||||
unsigned long currentMillis_Update_DateTime = millis();
|
||||
if (currentMillis_Update_DateTime - prevMill_Update_DateTime >= interval_Update_DateTime) {
|
||||
prevMill_Update_DateTime = currentMillis_Update_DateTime;
|
||||
get_DateTime();
|
||||
}
|
||||
|
||||
if (stringComplete) {
|
||||
Serial.print("Input String : ");
|
||||
Serial.println(inputString);
|
||||
|
||||
String command = getValue(inputString, ',', 0);
|
||||
|
||||
if (command == "SET") {
|
||||
Serial.println();
|
||||
Serial.println("------------");
|
||||
Serial.println("Set the Time and Date of the DS3231 RTC Module.");
|
||||
Serial.println("Incoming settings data : ");
|
||||
|
||||
d_year = getValue(inputString, ',', 1).toInt();
|
||||
d_month = getValue(inputString, ',', 2).toInt();
|
||||
d_day = getValue(inputString, ',', 3).toInt();
|
||||
t_hour = getValue(inputString, ',', 4).toInt();
|
||||
t_minute = getValue(inputString, ',',5).toInt();
|
||||
t_second = getValue(inputString, ',', 6).toInt();
|
||||
|
||||
Serial.print("- Year : ");Serial.println(d_year);
|
||||
Serial.print("- Month : ");Serial.println(d_month);
|
||||
Serial.print("- Day : ");Serial.println(d_day);
|
||||
Serial.print("- Hour : ");Serial.println(t_hour);
|
||||
Serial.print("- Minute : ");Serial.println(t_minute);
|
||||
Serial.print("- Second : ");Serial.println(t_second);
|
||||
|
||||
Serial.println("Set Time and Date...");
|
||||
rtc.adjust(DateTime(d_year, d_month, d_day, t_hour, t_minute, t_second));
|
||||
|
||||
Serial.println("Setting the Time and Date has been completed.");
|
||||
Serial.println("------------");
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
inputString = "";
|
||||
stringComplete = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,522 @@
|
||||
#ifndef PAGE_INDEX_H
|
||||
#define PAGE_INDEX_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
const char MAIN_page[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<title>Digital Clcok & Scrolling Text with ESP32 and P10 RGB 32x16</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<style>
|
||||
html {font-family: Helvetica, sans-serif;}
|
||||
h1 {font-size: 1.1rem; color:#1976D2;}
|
||||
|
||||
label {font-size: 14px;}
|
||||
|
||||
.div_Form {
|
||||
margin: auto;
|
||||
width: 90%;
|
||||
border:1px solid #D8D8D8;
|
||||
border-radius: 10px;
|
||||
background-color: #f2f2f2;
|
||||
padding: 9px 9px;
|
||||
}
|
||||
|
||||
.myButton {
|
||||
display: inline-block;
|
||||
padding: 3px 25px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
color: #fff;
|
||||
background-color: #1976D2;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px #999;
|
||||
}
|
||||
.myButton:hover {background-color: #104d89}
|
||||
.myButton:active {background-color: #104d89; box-shadow: 0 1px #666; transform: translateY(2px);}
|
||||
.myButton:disabled {background-color: #666; box-shadow: 0 1px #666; transform: translateY(2px);}
|
||||
|
||||
.myButtonX {background-color: #ff0000}
|
||||
.myButtonX:hover {background-color: #7a0101}
|
||||
|
||||
.div_Form_Input {display: table; margin: 0px; padding: 0px; box-sizing: border-box;}
|
||||
.div_Input_Text {display: table-cell; width: 100%;}
|
||||
.div_Input_Text > input {width:99.5%; margin-left: 0px; padding-left: 2px; box-sizing: border-box;}
|
||||
|
||||
table, th, td {
|
||||
border: 0px solid black;
|
||||
border-collapse: collapse;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.div_Logs {
|
||||
width: 100%;
|
||||
height: 150px;
|
||||
border: 1px solid #D8D8D8;
|
||||
border-radius: 5px;
|
||||
background-color: #ffffff;
|
||||
overflow-y: scroll;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 12px;
|
||||
padding: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div style="margin: 10px">
|
||||
<h1>Digital Clock & Scrolling Text with ESP32 and P10 RGB 32x16</h1>
|
||||
|
||||
<div class="div_Form">
|
||||
<div style="margin-bottom: 10px;">
|
||||
<label>Key : </label>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="text" id="key" maxlength="20" placeholder="Enter key">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 10px;">
|
||||
<button class="myButton" onclick="getSettings()">Get Settings</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="div_Form">
|
||||
<h3>Set Date & Time</h3>
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<td style="width:25%"><label>Year : </label></td>
|
||||
<td style="width:75%">
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="d_Year" min="2020" max="2099" value="2024">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Month : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="d_Month" min="1" max="12" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Day : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="d_Day" min="1" max="31" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Hour : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="t_Hour" min="0" max="23" value="12">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Minute : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="t_Minute" min="0" max="59" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Second : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="t_Second" min="0" max="59" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top: 10px;">
|
||||
<button class="myButton" onclick="setTimeDate()">Set Date & Time</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="div_Form">
|
||||
<h3>Display Settings</h3>
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<td style="width:25%"><label>Display Mode : </label></td>
|
||||
<td style="width:75%">
|
||||
<select id="input_Display_Mode" style="width:100%">
|
||||
<option value="1">Mode 1 (Manual Colors)</option>
|
||||
<option value="2">Mode 2 (Auto Color Change)</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Brightness : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="input_Brightness" min="0" max="255" value="125">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Scroll Speed : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="input_Scrolling_Speed" min="10" max="100" value="45">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top: 10px;">
|
||||
<button class="myButton" onclick="setDisplayMode()">Set Display Mode</button>
|
||||
<button class="myButton" onclick="setBrightness()">Set Brightness</button>
|
||||
<button class="myButton" onclick="setScrollingSpeed()">Set Scroll Speed</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="div_Form">
|
||||
<h3>Color Settings (Mode 1 Only)</h3>
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<td colspan="2"><label><strong>Clock Color (RGB)</strong></label></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width:10%"><label>R : </label></td>
|
||||
<td style="width:90%">
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Clock_R" min="0" max="255" value="255">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>G : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Clock_G" min="0" max="255" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>B : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Clock_B" min="0" max="255" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top: 10px;">
|
||||
<button class="myButton" onclick="setColorClock()">Set Clock Color</button>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<td colspan="2"><label><strong>Date Color (RGB)</strong></label></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width:10%"><label>R : </label></td>
|
||||
<td style="width:90%">
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Date_R" min="0" max="255" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>G : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Date_G" min="0" max="255" value="255">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>B : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Date_B" min="0" max="255" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top: 10px;">
|
||||
<button class="myButton" onclick="setColorDate()">Set Date Color</button>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<td colspan="2"><label><strong>Text Color (RGB)</strong></label></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width:10%"><label>R : </label></td>
|
||||
<td style="width:90%">
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Text_R" min="0" max="255" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>G : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Text_G" min="0" max="255" value="0">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>B : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="number" id="Color_Text_B" min="0" max="255" value="255">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top: 10px;">
|
||||
<button class="myButton" onclick="setColorText()">Set Text Color</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="div_Form">
|
||||
<h3>Scrolling Text</h3>
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<td><label>Text : </label></td>
|
||||
<td>
|
||||
<div class="div_Form_Input">
|
||||
<div class="div_Input_Text">
|
||||
<input type="text" id="input_Scrolling_Text" maxlength="150" placeholder="Enter scrolling text">
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="margin-top: 10px;">
|
||||
<button class="myButton" onclick="setScrollingText()">Set Scrolling Text</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="div_Form">
|
||||
<h3>System</h3>
|
||||
<button class="myButton myButtonX" onclick="resetSystem()">Reset System</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
//________________________________________________________________________________ sendCommandToESP32()
|
||||
function sendCommandToESP32(sta, msg) {
|
||||
var xmlhttp;
|
||||
if (window.XMLHttpRequest) {
|
||||
// code for IE7+, Firefox, Chrome, Opera, Safari
|
||||
xmlhttp = new XMLHttpRequest();
|
||||
} else {
|
||||
// code for IE6, IE5
|
||||
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
xmlhttp.onreadystatechange = function() {
|
||||
if (this.readyState == 4 && this.status == 200) {
|
||||
if (this.responseText == "+ERR") {
|
||||
alert("Error !\\rWrong Key !\\rPlease enter the correct key.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.responseText == "+ERR_DM") {
|
||||
alert("Error !\\rThis setting is only for Display Mode : 1. \\rPlease change the Display Mode to apply this setting.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sta == "get") {
|
||||
apply_the_Received_Settings(this.responseText);
|
||||
} else {
|
||||
alert("Settings applied successfully!");
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlhttp.open("GET", "settings?" + msg, true);
|
||||
xmlhttp.send();
|
||||
}
|
||||
//________________________________________________________________________________
|
||||
|
||||
function getSettings() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
sendCommandToESP32("get", "key=" + key + "&sta=get");
|
||||
}
|
||||
|
||||
function setTimeDate() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
var msg = "key=" + key + "&sta=setTimeDate";
|
||||
msg += "&d_Year=" + document.getElementById("d_Year").value;
|
||||
msg += "&d_Month=" + document.getElementById("d_Month").value;
|
||||
msg += "&d_Day=" + document.getElementById("d_Day").value;
|
||||
msg += "&t_Hour=" + document.getElementById("t_Hour").value;
|
||||
msg += "&t_Minute=" + document.getElementById("t_Minute").value;
|
||||
msg += "&t_Second=" + document.getElementById("t_Second").value;
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
|
||||
function setDisplayMode() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
var msg = "key=" + key + "&sta=setDisplayMode";
|
||||
msg += "&input_Display_Mode=" + document.getElementById("input_Display_Mode").value;
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
|
||||
function setBrightness() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
var msg = "key=" + key + "&sta=setBrightness";
|
||||
msg += "&input_Brightness=" + document.getElementById("input_Brightness").value;
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
|
||||
function setScrollingSpeed() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
var msg = "key=" + key + "&sta=setScrollingSpeed";
|
||||
msg += "&input_Scrolling_Speed=" + document.getElementById("input_Scrolling_Speed").value;
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
|
||||
function setColorClock() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
var msg = "key=" + key + "&sta=setColorClock";
|
||||
msg += "&Color_Clock_R=" + document.getElementById("Color_Clock_R").value;
|
||||
msg += "&Color_Clock_G=" + document.getElementById("Color_Clock_G").value;
|
||||
msg += "&Color_Clock_B=" + document.getElementById("Color_Clock_B").value;
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
|
||||
function setColorDate() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
var msg = "key=" + key + "&sta=setColorDate";
|
||||
msg += "&Color_Date_R=" + document.getElementById("Color_Date_R").value;
|
||||
msg += "&Color_Date_G=" + document.getElementById("Color_Date_G").value;
|
||||
msg += "&Color_Date_B=" + document.getElementById("Color_Date_B").value;
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
|
||||
function setColorText() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
var msg = "key=" + key + "&sta=setColorText";
|
||||
msg += "&Color_Text_R=" + document.getElementById("Color_Text_R").value;
|
||||
msg += "&Color_Text_G=" + document.getElementById("Color_Text_G").value;
|
||||
msg += "&Color_Text_B=" + document.getElementById("Color_Text_B").value;
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
|
||||
function setScrollingText() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
var msg = "key=" + key + "&sta=setScrollingText";
|
||||
msg += "&input_Scrolling_Text=" + encodeURIComponent(document.getElementById("input_Scrolling_Text").value);
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
|
||||
function resetSystem() {
|
||||
var key = document.getElementById("key").value;
|
||||
if (key == "") {
|
||||
alert("Please enter the key!");
|
||||
return;
|
||||
}
|
||||
if (confirm("Are you sure you want to reset the system?")) {
|
||||
var msg = "key=" + key + "&sta=resetSystem";
|
||||
sendCommandToESP32("set", msg);
|
||||
}
|
||||
}
|
||||
|
||||
function apply_the_Received_Settings(receivedSettings) {
|
||||
// Fonction pour appliquer les paramètres reçus
|
||||
console.log("Settings received:", receivedSettings);
|
||||
// Ici vous pouvez analyser la réponse et remplir les champs du formulaire
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
)=====";
|
||||
|
||||
#endif // PAGE_INDEX_H
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
; Configuration commune
|
||||
[env]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
||||
monitor_speed = 115200
|
||||
monitor_filters = esp32_exception_decoder
|
||||
upload_speed = 921600
|
||||
board_build.f_cpu = 240000000L
|
||||
board_build.f_flash = 80000000L
|
||||
board_build.partitions = default.csv
|
||||
build_flags =
|
||||
-DCORE_DEBUG_LEVEL=0
|
||||
-DARDUINO_USB_CDC_ON_BOOT=0
|
||||
; Configuration par défaut pour un seul panneau 32x16
|
||||
-DMATRIX_WIDTH=32
|
||||
-DMATRIX_HEIGHT=16
|
||||
-DMATRIX_PANELS_X=1
|
||||
-DMATRIX_PANELS_Y=1
|
||||
|
||||
; ==========================================
|
||||
; ENVIRONNEMENT PRINCIPAL - Horloge complète
|
||||
; ==========================================
|
||||
[env:main]
|
||||
src_filter = +<main.cpp>
|
||||
lib_deps =
|
||||
adafruit/Adafruit BusIO@^1.16.1
|
||||
adafruit/Adafruit GFX Library@^1.11.9
|
||||
adafruit/RTClib@^2.1.4
|
||||
https://github.com/2dom/PxMatrix.git
|
||||
|
||||
; ==========================================
|
||||
; ENVIRONNEMENTS DE TEST
|
||||
; ==========================================
|
||||
|
||||
; Test du module RTC DS3231
|
||||
[env:rtc_test]
|
||||
src_filter = +<../examples/rtc_test.cpp>
|
||||
lib_deps =
|
||||
adafruit/RTClib@^2.1.4
|
||||
|
||||
; Test du panneau P10 RGB
|
||||
[env:p10_test]
|
||||
src_filter = +<../examples/p10_test.cpp>
|
||||
lib_deps =
|
||||
adafruit/Adafruit BusIO@^1.16.1
|
||||
adafruit/Adafruit GFX Library@^1.11.9
|
||||
https://github.com/2dom/PxMatrix.git
|
||||
|
||||
; Effacement de la mémoire NVS
|
||||
[env:nvs_erase]
|
||||
src_filter = +<../examples/nvs_erase.cpp>
|
||||
|
||||
; ==========================================
|
||||
; ENVIRONNEMENT DE DÉVELOPPEMENT
|
||||
; ==========================================
|
||||
[env:debug]
|
||||
src_filter = +<main.cpp>
|
||||
lib_deps =
|
||||
adafruit/Adafruit BusIO@^1.16.1
|
||||
adafruit/Adafruit GFX Library@^1.11.9
|
||||
adafruit/RTClib@^2.1.4
|
||||
https://github.com/2dom/PxMatrix.git
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DCORE_DEBUG_LEVEL=5
|
||||
-DDEBUG_ESP_PORT=Serial
|
||||
|
||||
; Configuration pour OTA (optionnel)
|
||||
; Décommentez et configurez selon vos besoins
|
||||
;[env:ota]
|
||||
;extends = env:main
|
||||
;upload_protocol = espota
|
||||
;upload_port = 192.168.1.100
|
||||
;upload_flags = --auth=your_ota_password
|
||||
|
||||
; ==========================================
|
||||
; CONFIGURATIONS PANNEAUX MULTIPLES
|
||||
; ==========================================
|
||||
|
||||
; Configuration 2 panneaux horizontaux (64x16)
|
||||
[env:cascade_2x1]
|
||||
extends = env:main
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMATRIX_WIDTH=32
|
||||
-DMATRIX_HEIGHT=16
|
||||
-DMATRIX_PANELS_X=2
|
||||
-DMATRIX_PANELS_Y=1
|
||||
-DCASCADE_MODE=1
|
||||
|
||||
; Configuration 3 panneaux horizontaux (96x16)
|
||||
[env:cascade_3x1]
|
||||
extends = env:main
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMATRIX_WIDTH=32
|
||||
-DMATRIX_HEIGHT=16
|
||||
-DMATRIX_PANELS_X=3
|
||||
-DMATRIX_PANELS_Y=1
|
||||
-DCASCADE_MODE=1
|
||||
|
||||
; Configuration 4 panneaux horizontaux (128x16)
|
||||
[env:cascade_4x1]
|
||||
extends = env:main
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMATRIX_WIDTH=32
|
||||
-DMATRIX_HEIGHT=16
|
||||
-DMATRIX_PANELS_X=4
|
||||
-DMATRIX_PANELS_Y=1
|
||||
-DCASCADE_MODE=1
|
||||
|
||||
; Configuration 2x2 panneaux (64x32)
|
||||
[env:cascade_2x2]
|
||||
extends = env:main
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMATRIX_WIDTH=32
|
||||
-DMATRIX_HEIGHT=16
|
||||
-DMATRIX_PANELS_X=2
|
||||
-DMATRIX_PANELS_Y=2
|
||||
-DCASCADE_MODE=1
|
||||
|
||||
; Configuration 6 panneaux horizontaux (192x16)
|
||||
[env:cascade_6x1]
|
||||
extends = env:main
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMATRIX_WIDTH=32
|
||||
-DMATRIX_HEIGHT=16
|
||||
-DMATRIX_PANELS_X=6
|
||||
-DMATRIX_PANELS_Y=1
|
||||
-DCASCADE_MODE=1
|
||||
|
||||
; Configuration 8 panneaux horizontaux (256x16)
|
||||
[env:cascade_8x1]
|
||||
extends = env:main
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMATRIX_WIDTH=32
|
||||
-DMATRIX_HEIGHT=16
|
||||
-DMATRIX_PANELS_X=8
|
||||
-DMATRIX_PANELS_Y=1
|
||||
-DCASCADE_MODE=1
|
||||
|
||||
; Test pour panneaux multiples
|
||||
[env:test_cascade]
|
||||
src_filter = +<../examples/cascade_test.cpp>
|
||||
lib_deps =
|
||||
adafruit/Adafruit BusIO@^1.16.1
|
||||
adafruit/Adafruit GFX Library@^1.11.9
|
||||
https://github.com/2dom/PxMatrix.git
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-DMATRIX_WIDTH=32
|
||||
-DMATRIX_HEIGHT=16
|
||||
-DMATRIX_PANELS_X=2
|
||||
-DMATRIX_PANELS_Y=1
|
||||
-DCASCADE_MODE=1
|
||||
+822
@@ -0,0 +1,822 @@
|
||||
/**
|
||||
* ESP32 P10 RGB 32x16 Digital Clock with Web Server
|
||||
* Compatible with PlatformIO
|
||||
*
|
||||
* Hardware Requirements:
|
||||
* - ESP32 DEVKIT V1
|
||||
* - P10 RGB 32x16 HUB75 Panel
|
||||
* - DS3231 RTC Module
|
||||
* - 5V Power Supply
|
||||
*
|
||||
* Libraries:
|
||||
* - Adafruit BusIO
|
||||
* - Adafruit GFX Library
|
||||
* - PxMatrix Library
|
||||
* - RTClib
|
||||
*/
|
||||
|
||||
// Defines pour la fréquence SPI (réduire si du bruit apparaît sur l'affichage)
|
||||
#define PxMATRIX_SPI_FREQUENCY 10000000
|
||||
|
||||
// Inclusion des bibliothèques
|
||||
#include <Arduino.h>
|
||||
#include <PxMatrix.h>
|
||||
#include <RTClib.h>
|
||||
#include <Preferences.h>
|
||||
#include <WiFi.h>
|
||||
#include <WebServer.h>
|
||||
#include <nvs_flash.h>
|
||||
#include "PageIndex.h"
|
||||
|
||||
// Pins pour la matrice LED
|
||||
#define P_LAT 5
|
||||
#define P_A 19
|
||||
#define P_B 23
|
||||
#define P_C 18
|
||||
#define P_OE 4
|
||||
|
||||
// Configuration des panneaux - définie par les build flags ou valeurs par défaut
|
||||
#ifndef MATRIX_WIDTH
|
||||
#define MATRIX_WIDTH 32
|
||||
#endif
|
||||
|
||||
#ifndef MATRIX_HEIGHT
|
||||
#define MATRIX_HEIGHT 16
|
||||
#endif
|
||||
|
||||
#ifndef MATRIX_PANELS_X
|
||||
#define MATRIX_PANELS_X 1
|
||||
#endif
|
||||
|
||||
#ifndef MATRIX_PANELS_Y
|
||||
#define MATRIX_PANELS_Y 1
|
||||
#endif
|
||||
|
||||
// Calcul des dimensions totales
|
||||
#define TOTAL_WIDTH (MATRIX_WIDTH * MATRIX_PANELS_X)
|
||||
#define TOTAL_HEIGHT (MATRIX_HEIGHT * MATRIX_PANELS_Y)
|
||||
|
||||
// Configuration du timer
|
||||
hw_timer_t * timer = NULL;
|
||||
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
// Temps d'affichage (plus élevé = plus lumineux, mais attention aux crashs)
|
||||
uint8_t display_draw_time = 30; // 30-70 est généralement correct
|
||||
|
||||
// Objet matrice avec dimensions totales calculées
|
||||
PxMATRIX display(TOTAL_WIDTH, TOTAL_HEIGHT, P_LAT, P_OE, P_A, P_B, P_C);
|
||||
|
||||
// Couleurs prédéfinies
|
||||
uint16_t myRED = display.color565(255, 0, 0);
|
||||
uint16_t myGREEN = display.color565(0, 255, 0);
|
||||
uint16_t myBLUE = display.color565(0, 0, 255);
|
||||
uint16_t myYELLOW = display.color565(255, 255, 0);
|
||||
uint16_t myCYAN = display.color565(0, 255, 255);
|
||||
uint16_t myFUCHSIA = display.color565(255, 0, 255);
|
||||
uint16_t myWHITE = display.color565(255, 255, 255);
|
||||
uint16_t myBLACK = display.color565(0, 0, 0);
|
||||
|
||||
uint16_t myCOLOR_ARRAY[7] = {myRED, myGREEN, myBLUE, myYELLOW, myCYAN, myFUCHSIA, myWHITE};
|
||||
int cnt_Color = 0;
|
||||
int myCOLOR_ARRAY_Length = sizeof(myCOLOR_ARRAY) / sizeof(myCOLOR_ARRAY[0]);
|
||||
|
||||
// Variables pour le texte défilant
|
||||
unsigned long prevMill_Scroll_Text = 0;
|
||||
int scrolling_Y_Pos = 0;
|
||||
long scrolling_X_Pos;
|
||||
long scrolling_X_Pos_CT;
|
||||
uint16_t scrolling_Text_Color;
|
||||
uint16_t text_Color;
|
||||
char text_Scrolling_Text[151];
|
||||
uint16_t text_Length_In_Pixel;
|
||||
bool set_up_Scrolling_Text_Length = true;
|
||||
bool start_Scroll_Text = false;
|
||||
byte scrolling_text_Display_Order = 0;
|
||||
bool reset_Scrolling_Text = false;
|
||||
|
||||
// Variables de temps
|
||||
unsigned long prevMill_Update_Time = 0;
|
||||
const long interval_Update_Time = 1000;
|
||||
unsigned long prevMill_Show_Clock = 0;
|
||||
const long interval_Show_Clock = 500;
|
||||
|
||||
// Variables pour la date et l'heure
|
||||
char daysOfTheWeek[7][10] = {"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"};
|
||||
char chr_t_Minute[3];
|
||||
byte minute_Val, last_minute_Val;
|
||||
char chr_t_Hour[3];
|
||||
char day_and_date_Text[25];
|
||||
bool blink_Colon = false;
|
||||
uint16_t clock_Color;
|
||||
uint16_t day_and_date_Text_Color;
|
||||
|
||||
// Variables de configuration
|
||||
int d_Year;
|
||||
byte d_Month, d_Day;
|
||||
byte t_Hour, t_Minute, t_Second;
|
||||
byte input_Display_Mode = 1;
|
||||
byte input_Brightness = 125;
|
||||
byte input_Scrolling_Speed = 45;
|
||||
int Color_Clock_R = 255, Color_Clock_G = 0, Color_Clock_B = 0;
|
||||
int Color_Date_R = 0, Color_Date_G = 255, Color_Date_B = 0;
|
||||
int Color_Text_R = 0, Color_Text_G = 0, Color_Text_B = 255;
|
||||
char input_Scrolling_Text[151] = "ESP32 P10 RGB Digital Clock with PlatformIO";
|
||||
|
||||
// Configuration WiFi - Modifiez selon vos besoins
|
||||
const char* ssid = "YOUR_WIFI_SSID";
|
||||
const char* password = "YOUR_WIFI_PASSWORD";
|
||||
|
||||
// Configuration Point d'accès (si pas de WiFi)
|
||||
const char* ap_ssid = "ESP32_Clock";
|
||||
const char* ap_password = "esp32clock";
|
||||
|
||||
// Clé de sécurité pour l'interface web
|
||||
#define KEY_TXT "p10rgbesp32ws"
|
||||
|
||||
// Mode de fonctionnement WiFi
|
||||
bool useStationMode = true; // true = se connecter au WiFi, false = créer un point d'accès
|
||||
|
||||
// Objets RTC et Preferences
|
||||
RTC_DS3231 rtc;
|
||||
Preferences preferences;
|
||||
|
||||
// Serveur web
|
||||
WebServer server(80);
|
||||
|
||||
// Gestionnaire d'interruption pour l'affichage
|
||||
void IRAM_ATTR display_updater() {
|
||||
portENTER_CRITICAL_ISR(&timerMux);
|
||||
display.display(display_draw_time);
|
||||
portEXIT_CRITICAL_ISR(&timerMux);
|
||||
}
|
||||
|
||||
// Activation/désactivation du timer d'affichage
|
||||
void display_update_enable(bool is_enable) {
|
||||
if (is_enable) {
|
||||
timer = timerBegin(0, 80, true);
|
||||
timerAttachInterrupt(timer, &display_updater, true);
|
||||
timerAlarmWrite(timer, 1500, true);
|
||||
timerAlarmEnable(timer);
|
||||
} else {
|
||||
timerDetachInterrupt(timer);
|
||||
timerAlarmDisable(timer);
|
||||
}
|
||||
}
|
||||
|
||||
// Connexion WiFi
|
||||
void connecting_To_WiFi() {
|
||||
Serial.println("\n-------------WIFI mode");
|
||||
Serial.println("WIFI mode : STA");
|
||||
WiFi.mode(WIFI_STA);
|
||||
Serial.println("-------------");
|
||||
delay(1000);
|
||||
|
||||
Serial.println("\n-------------Connection");
|
||||
Serial.print("Connecting to ");
|
||||
Serial.println(ssid);
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
int connecting_process_timed_out = 40; // 20 secondes timeout
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
Serial.print(".");
|
||||
delay(500);
|
||||
if(connecting_process_timed_out > 0) connecting_process_timed_out--;
|
||||
if(connecting_process_timed_out == 0) {
|
||||
Serial.println("\nFailed to connect to WiFi. Switching to AP mode.");
|
||||
useStationMode = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WiFi.status() == WL_CONNECTED) {
|
||||
Serial.println("\nWiFi connected");
|
||||
Serial.print("Successfully connected to : ");
|
||||
Serial.println(ssid);
|
||||
Serial.print("IP address : ");
|
||||
Serial.println(WiFi.localIP());
|
||||
}
|
||||
Serial.println("-------------");
|
||||
}
|
||||
|
||||
// Configuration du point d'accès
|
||||
void set_ESP32_Access_Point() {
|
||||
Serial.println("\n-------------");
|
||||
Serial.println("WIFI mode : AP");
|
||||
WiFi.mode(WIFI_AP);
|
||||
Serial.println("-------------");
|
||||
delay(1000);
|
||||
|
||||
Serial.println("\n-------------");
|
||||
Serial.println("Setting up ESP32 to be an Access Point.");
|
||||
WiFi.softAP(ap_ssid, ap_password);
|
||||
delay(1000);
|
||||
|
||||
IPAddress local_ip(192, 168, 1, 1);
|
||||
IPAddress gateway(192, 168, 1, 1);
|
||||
IPAddress subnet(255, 255, 255, 0);
|
||||
|
||||
WiFi.softAPConfig(local_ip, gateway, subnet);
|
||||
Serial.println("-------------");
|
||||
Serial.print("SSID name : ");
|
||||
Serial.println(ap_ssid);
|
||||
Serial.print("IP address : ");
|
||||
Serial.println(WiFi.softAPIP());
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// Fonction pour obtenir la largeur du texte en pixels
|
||||
uint16_t getTextWidth(const char* text) {
|
||||
int16_t x1, y1;
|
||||
uint16_t w, h;
|
||||
display.getTextBounds(text, 0, 0, &x1, &y1, &w, &h);
|
||||
return w;
|
||||
}
|
||||
|
||||
// Fonction pour dessiner les deux points de l'heure
|
||||
void drawColon(int16_t x, int16_t y, uint16_t colonColor) {
|
||||
display.drawPixel(x, y, colonColor);
|
||||
display.drawPixel(x+1, y, colonColor);
|
||||
display.drawPixel(x, y+1, colonColor);
|
||||
display.drawPixel(x+1, y+1, colonColor);
|
||||
|
||||
display.drawPixel(x, y+3, colonColor);
|
||||
display.drawPixel(x+1, y+3, colonColor);
|
||||
display.drawPixel(x, y+4, colonColor);
|
||||
display.drawPixel(x+1, y+4, colonColor);
|
||||
}
|
||||
|
||||
// Fonction de texte défilant adaptée aux panneaux multiples
|
||||
void run_Scrolling_Text(uint8_t st_Y_Pos, byte st_Speed, char * st_Text, uint16_t st_Color) {
|
||||
if (start_Scroll_Text == true && set_up_Scrolling_Text_Length == true) {
|
||||
if (strlen(st_Text) > 0) {
|
||||
text_Length_In_Pixel = getTextWidth(st_Text);
|
||||
scrolling_X_Pos = TOTAL_WIDTH; // Utiliser la largeur totale
|
||||
set_up_Scrolling_Text_Length = false;
|
||||
} else {
|
||||
start_Scroll_Text = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long currentMillis_Scroll_Text = millis();
|
||||
if (currentMillis_Scroll_Text - prevMill_Scroll_Text >= st_Speed) {
|
||||
prevMill_Scroll_Text = currentMillis_Scroll_Text;
|
||||
|
||||
scrolling_X_Pos--;
|
||||
if (scrolling_X_Pos < -(TOTAL_WIDTH + text_Length_In_Pixel)) { // Utiliser la largeur totale
|
||||
set_up_Scrolling_Text_Length = true;
|
||||
start_Scroll_Text = false;
|
||||
return;
|
||||
}
|
||||
|
||||
scrolling_X_Pos_CT = scrolling_X_Pos + 1;
|
||||
|
||||
display.setTextColor(myBLACK);
|
||||
display.setCursor(scrolling_X_Pos_CT, st_Y_Pos);
|
||||
display.print(st_Text);
|
||||
|
||||
display.setTextColor(st_Color);
|
||||
display.setCursor(scrolling_X_Pos, st_Y_Pos);
|
||||
display.print(st_Text);
|
||||
}
|
||||
}
|
||||
|
||||
// Récupération de l'heure
|
||||
void get_Time() {
|
||||
DateTime now = rtc.now();
|
||||
minute_Val = now.minute();
|
||||
sprintf(chr_t_Hour, "%02d", now.hour());
|
||||
sprintf(chr_t_Minute, "%02d", now.minute());
|
||||
}
|
||||
|
||||
// Récupération de la date
|
||||
void get_Date() {
|
||||
DateTime now = rtc.now();
|
||||
sprintf(day_and_date_Text, "%s, %02d-%02d-%d",
|
||||
daysOfTheWeek[now.dayOfTheWeek()],
|
||||
now.day(), now.month(), now.year());
|
||||
}
|
||||
|
||||
// Chargement des paramètres depuis la mémoire flash
|
||||
void loadSettings() {
|
||||
preferences.begin("mySettings", true);
|
||||
|
||||
input_Display_Mode = preferences.getInt("input_DM", 1);
|
||||
input_Brightness = preferences.getInt("input_BRT", 125);
|
||||
input_Scrolling_Speed = preferences.getInt("input_SS", 45);
|
||||
Color_Clock_R = preferences.getInt("CC_R", 255);
|
||||
Color_Clock_G = preferences.getInt("CC_G", 0);
|
||||
Color_Clock_B = preferences.getInt("CC_B", 0);
|
||||
Color_Date_R = preferences.getInt("DC_R", 0);
|
||||
Color_Date_G = preferences.getInt("DC_G", 255);
|
||||
Color_Date_B = preferences.getInt("DC_B", 0);
|
||||
Color_Text_R = preferences.getInt("CT_R", 0);
|
||||
Color_Text_G = preferences.getInt("CT_G", 0);
|
||||
Color_Text_B = preferences.getInt("CT_B", 255);
|
||||
|
||||
String savedText = preferences.getString("scrollText", "ESP32 P10 RGB Digital Clock with PlatformIO");
|
||||
strcpy(input_Scrolling_Text, savedText.c_str());
|
||||
|
||||
preferences.end();
|
||||
|
||||
// Application des paramètres
|
||||
display.setBrightness(input_Brightness);
|
||||
if (input_Display_Mode == 1) {
|
||||
clock_Color = display.color565(Color_Clock_R, Color_Clock_G, Color_Clock_B);
|
||||
day_and_date_Text_Color = display.color565(Color_Date_R, Color_Date_G, Color_Date_B);
|
||||
text_Color = display.color565(Color_Text_R, Color_Text_G, Color_Text_B);
|
||||
}
|
||||
}
|
||||
|
||||
// Gestionnaire de la page principale
|
||||
void handleRoot() {
|
||||
server.send(200, "text/html", MAIN_page);
|
||||
}
|
||||
|
||||
// Gestionnaire des paramètres
|
||||
void handleSettings() {
|
||||
String incoming_Settings = server.arg("key");
|
||||
|
||||
Serial.println("\n-------------Settings");
|
||||
Serial.print("Key : ");
|
||||
Serial.println(incoming_Settings);
|
||||
|
||||
if (incoming_Settings != KEY_TXT) {
|
||||
server.send(200, "text/plain", "+ERR");
|
||||
Serial.println("Wrong key!");
|
||||
Serial.println("-------------");
|
||||
return;
|
||||
}
|
||||
|
||||
incoming_Settings = server.arg("sta");
|
||||
|
||||
// Définir la date et l'heure
|
||||
if (incoming_Settings == "setTimeDate") {
|
||||
d_Year = server.arg("d_Year").toInt();
|
||||
d_Month = server.arg("d_Month").toInt();
|
||||
d_Day = server.arg("d_Day").toInt();
|
||||
t_Hour = server.arg("t_Hour").toInt();
|
||||
t_Minute = server.arg("t_Minute").toInt();
|
||||
t_Second = server.arg("t_Second").toInt();
|
||||
|
||||
Serial.println("Set Time and Date.");
|
||||
Serial.printf("DateTime : %02d-%02d-%d %02d:%02d:%02d\n", d_Day, d_Month, d_Year, t_Hour, t_Minute, t_Second);
|
||||
|
||||
rtc.adjust(DateTime(d_Year, d_Month, d_Day, t_Hour, t_Minute, t_Second));
|
||||
Serial.println("Setting completed.");
|
||||
}
|
||||
|
||||
// Définir le mode d'affichage
|
||||
else if (incoming_Settings == "setDisplayMode") {
|
||||
input_Display_Mode = server.arg("input_Display_Mode").toInt();
|
||||
|
||||
Serial.print("Set Display Mode : ");
|
||||
Serial.println(input_Display_Mode);
|
||||
|
||||
display_update_enable(false);
|
||||
delay(100);
|
||||
|
||||
preferences.begin("mySettings", false);
|
||||
preferences.putInt("input_DM", input_Display_Mode);
|
||||
preferences.end();
|
||||
|
||||
display_update_enable(true);
|
||||
|
||||
if (input_Display_Mode == 1) {
|
||||
clock_Color = display.color565(Color_Clock_R, Color_Clock_G, Color_Clock_B);
|
||||
day_and_date_Text_Color = display.color565(Color_Date_R, Color_Date_G, Color_Date_B);
|
||||
text_Color = display.color565(Color_Text_R, Color_Text_G, Color_Text_B);
|
||||
}
|
||||
|
||||
display.clearDisplay();
|
||||
reset_Scrolling_Text = true;
|
||||
scrolling_text_Display_Order = 0;
|
||||
}
|
||||
|
||||
// Définir la luminosité
|
||||
else if (incoming_Settings == "setBrightness") {
|
||||
input_Brightness = server.arg("input_Brightness").toInt();
|
||||
if (input_Brightness > 255) input_Brightness = 255;
|
||||
if (input_Brightness < 0) input_Brightness = 0;
|
||||
|
||||
Serial.print("Set Brightness : ");
|
||||
Serial.println(input_Brightness);
|
||||
|
||||
display_update_enable(false);
|
||||
delay(100);
|
||||
|
||||
preferences.begin("mySettings", false);
|
||||
preferences.putInt("input_BRT", input_Brightness);
|
||||
preferences.end();
|
||||
|
||||
display_update_enable(true);
|
||||
display.setBrightness(input_Brightness);
|
||||
}
|
||||
|
||||
// Définir la vitesse de défilement
|
||||
else if (incoming_Settings == "setScrollingSpeed") {
|
||||
input_Scrolling_Speed = server.arg("input_Scrolling_Speed").toInt();
|
||||
if (input_Scrolling_Speed > 100) input_Scrolling_Speed = 100;
|
||||
if (input_Scrolling_Speed < 10) input_Scrolling_Speed = 10;
|
||||
|
||||
Serial.print("Set Scrolling Speed : ");
|
||||
Serial.println(input_Scrolling_Speed);
|
||||
|
||||
preferences.begin("mySettings", false);
|
||||
preferences.putInt("input_SS", input_Scrolling_Speed);
|
||||
preferences.end();
|
||||
}
|
||||
|
||||
// Définir la couleur de l'horloge
|
||||
else if (incoming_Settings == "setColorClock") {
|
||||
if (input_Display_Mode == 2) {
|
||||
server.send(200, "text/plain", "+ERR_DM");
|
||||
Serial.println("-------------");
|
||||
return;
|
||||
}
|
||||
|
||||
Color_Clock_R = server.arg("Color_Clock_R").toInt();
|
||||
Color_Clock_G = server.arg("Color_Clock_G").toInt();
|
||||
Color_Clock_B = server.arg("Color_Clock_B").toInt();
|
||||
|
||||
Serial.printf("Set Clock Color (RGB) : %d,%d,%d\n", Color_Clock_R, Color_Clock_G, Color_Clock_B);
|
||||
|
||||
display_update_enable(false);
|
||||
delay(100);
|
||||
|
||||
preferences.begin("mySettings", false);
|
||||
preferences.putInt("CC_R", Color_Clock_R);
|
||||
preferences.putInt("CC_G", Color_Clock_G);
|
||||
preferences.putInt("CC_B", Color_Clock_B);
|
||||
preferences.end();
|
||||
|
||||
display_update_enable(true);
|
||||
clock_Color = display.color565(Color_Clock_R, Color_Clock_G, Color_Clock_B);
|
||||
}
|
||||
|
||||
// Définir la couleur de la date
|
||||
else if (incoming_Settings == "setColorDate") {
|
||||
if (input_Display_Mode == 2) {
|
||||
server.send(200, "text/plain", "+ERR_DM");
|
||||
Serial.println("-------------");
|
||||
return;
|
||||
}
|
||||
|
||||
Color_Date_R = server.arg("Color_Date_R").toInt();
|
||||
Color_Date_G = server.arg("Color_Date_G").toInt();
|
||||
Color_Date_B = server.arg("Color_Date_B").toInt();
|
||||
|
||||
Serial.printf("Set Date Color (RGB) : %d,%d,%d\n", Color_Date_R, Color_Date_G, Color_Date_B);
|
||||
|
||||
display_update_enable(false);
|
||||
delay(100);
|
||||
|
||||
preferences.begin("mySettings", false);
|
||||
preferences.putInt("DC_R", Color_Date_R);
|
||||
preferences.putInt("DC_G", Color_Date_G);
|
||||
preferences.putInt("DC_B", Color_Date_B);
|
||||
preferences.end();
|
||||
|
||||
display_update_enable(true);
|
||||
day_and_date_Text_Color = display.color565(Color_Date_R, Color_Date_G, Color_Date_B);
|
||||
}
|
||||
|
||||
// Définir la couleur du texte
|
||||
else if (incoming_Settings == "setColorText") {
|
||||
if (input_Display_Mode == 2) {
|
||||
server.send(200, "text/plain", "+ERR_DM");
|
||||
Serial.println("-------------");
|
||||
return;
|
||||
}
|
||||
|
||||
Color_Text_R = server.arg("Color_Text_R").toInt();
|
||||
Color_Text_G = server.arg("Color_Text_G").toInt();
|
||||
Color_Text_B = server.arg("Color_Text_B").toInt();
|
||||
|
||||
Serial.printf("Set Text Color (RGB) : %d,%d,%d\n", Color_Text_R, Color_Text_G, Color_Text_B);
|
||||
|
||||
display_update_enable(false);
|
||||
delay(100);
|
||||
|
||||
preferences.begin("mySettings", false);
|
||||
preferences.putInt("CT_R", Color_Text_R);
|
||||
preferences.putInt("CT_G", Color_Text_G);
|
||||
preferences.putInt("CT_B", Color_Text_B);
|
||||
preferences.end();
|
||||
|
||||
display_update_enable(true);
|
||||
text_Color = display.color565(Color_Text_R, Color_Text_G, Color_Text_B);
|
||||
}
|
||||
|
||||
// Définir le texte défilant
|
||||
else if (incoming_Settings == "setScrollingText") {
|
||||
String scrollText = server.arg("input_Scrolling_Text");
|
||||
if (scrollText.length() > 150) scrollText = scrollText.substring(0, 150);
|
||||
strcpy(input_Scrolling_Text, scrollText.c_str());
|
||||
|
||||
Serial.print("Set Scrolling Text : ");
|
||||
Serial.println(input_Scrolling_Text);
|
||||
|
||||
preferences.begin("mySettings", false);
|
||||
preferences.putString("scrollText", scrollText);
|
||||
preferences.end();
|
||||
|
||||
reset_Scrolling_Text = true;
|
||||
scrolling_text_Display_Order = 0;
|
||||
}
|
||||
|
||||
// Reset du système
|
||||
else if (incoming_Settings == "resetSystem") {
|
||||
Serial.println("System Reset requested");
|
||||
server.send(200, "text/plain", "+OK");
|
||||
delay(1000);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
server.send(200, "text/plain", "+OK");
|
||||
Serial.println("-------------");
|
||||
}
|
||||
|
||||
// Configuration et démarrage du serveur
|
||||
void prepare_and_start_The_Server() {
|
||||
server.on("/", handleRoot);
|
||||
server.on("/settings", handleSettings);
|
||||
delay(500);
|
||||
|
||||
server.begin();
|
||||
Serial.println("\nHTTP server started");
|
||||
|
||||
if (useStationMode) {
|
||||
Serial.print("Open http://");
|
||||
Serial.print(WiFi.localIP());
|
||||
Serial.println(" in your browser");
|
||||
} else {
|
||||
Serial.print("Connect to WiFi network: ");
|
||||
Serial.println(ap_ssid);
|
||||
Serial.print("Then open http://");
|
||||
Serial.print(WiFi.softAPIP());
|
||||
Serial.println(" in your browser");
|
||||
}
|
||||
|
||||
Serial.println("Use key: " KEY_TXT);
|
||||
delay(500);
|
||||
}
|
||||
|
||||
void setup() {
|
||||
delay(1000);
|
||||
Serial.begin(115200);
|
||||
Serial.println("\n=== ESP32 P10 RGB Digital Clock ===");
|
||||
Serial.println("Version: PlatformIO Compatible with Cascade Support");
|
||||
|
||||
// Affichage de la configuration des panneaux
|
||||
Serial.println("\n--- Configuration Panneaux ---");
|
||||
Serial.printf("Panneaux X: %d\n", MATRIX_PANELS_X);
|
||||
Serial.printf("Panneaux Y: %d\n", MATRIX_PANELS_Y);
|
||||
Serial.printf("Taille panneau: %dx%d pixels\n", MATRIX_WIDTH, MATRIX_HEIGHT);
|
||||
Serial.printf("Taille totale: %dx%d pixels\n", TOTAL_WIDTH, TOTAL_HEIGHT);
|
||||
Serial.printf("Nombre total panneaux: %d\n", MATRIX_PANELS_X * MATRIX_PANELS_Y);
|
||||
|
||||
// Ajustement automatique de la luminosité selon le nombre de panneaux
|
||||
int auto_brightness = 125;
|
||||
if (MATRIX_PANELS_X > 2) auto_brightness = 100;
|
||||
if (MATRIX_PANELS_X > 4) auto_brightness = 80;
|
||||
if (MATRIX_PANELS_X > 6) auto_brightness = 60;
|
||||
input_Brightness = auto_brightness;
|
||||
|
||||
Serial.printf("Luminosité auto-ajustée: %d\n", auto_brightness);
|
||||
Serial.println("------------------------------");
|
||||
|
||||
// Initialisation du RTC
|
||||
Serial.println("\n------------");
|
||||
Serial.println("Starting DS3231 RTC module...");
|
||||
if (!rtc.begin()) {
|
||||
Serial.println("Couldn't find RTC");
|
||||
while (1) delay(10);
|
||||
}
|
||||
Serial.println("DS3231 RTC module started successfully");
|
||||
Serial.println("------------");
|
||||
|
||||
// Initialisation de l'affichage
|
||||
display.begin(8); // Valeur 8 pour un panneau 1/8 scan
|
||||
delay(100);
|
||||
|
||||
// Activation des interruptions timer
|
||||
display_update_enable(true);
|
||||
delay(100);
|
||||
|
||||
display.clearDisplay();
|
||||
delay(500);
|
||||
|
||||
// Chargement des paramètres
|
||||
loadSettings();
|
||||
|
||||
// Appliquer la luminosité ajustée si pas de sauvegarde
|
||||
display.setBrightness(input_Brightness);
|
||||
|
||||
// Test d'affichage des couleurs avec message adapté
|
||||
Serial.println("Testing display colors...");
|
||||
|
||||
// Test de bordures pour vérifier l'alignement (panneaux multiples)
|
||||
if (MATRIX_PANELS_X > 1 || MATRIX_PANELS_Y > 1) {
|
||||
Serial.println("Testing panel alignment...");
|
||||
|
||||
// Bordure extérieure
|
||||
display.drawRect(0, 0, TOTAL_WIDTH, TOTAL_HEIGHT, myWHITE);
|
||||
delay(1000);
|
||||
|
||||
// Lignes de séparation entre panneaux
|
||||
for (int i = 1; i < MATRIX_PANELS_X; i++) {
|
||||
int x = i * MATRIX_WIDTH;
|
||||
display.drawLine(x, 0, x, TOTAL_HEIGHT - 1, myRED);
|
||||
}
|
||||
for (int i = 1; i < MATRIX_PANELS_Y; i++) {
|
||||
int y = i * MATRIX_HEIGHT;
|
||||
display.drawLine(0, y, TOTAL_WIDTH - 1, y, myGREEN);
|
||||
}
|
||||
delay(2000);
|
||||
display.clearDisplay();
|
||||
}
|
||||
|
||||
// Test des couleurs
|
||||
display.fillScreen(myRED);
|
||||
delay(1000);
|
||||
display.fillScreen(myGREEN);
|
||||
delay(1000);
|
||||
display.fillScreen(myBLUE);
|
||||
delay(1000);
|
||||
display.fillScreen(myWHITE);
|
||||
delay(1000);
|
||||
|
||||
display.clearDisplay();
|
||||
delay(500);
|
||||
|
||||
display.setTextWrap(false);
|
||||
display.setTextSize(1);
|
||||
display.setRotation(0);
|
||||
|
||||
// Affichage du message de démarrage adapté
|
||||
display.setTextColor(myWHITE);
|
||||
|
||||
// Calculer la position centrée pour le texte
|
||||
String startMsg = "ESP32 CLOCK";
|
||||
if (MATRIX_PANELS_X > 1) {
|
||||
startMsg = String(MATRIX_PANELS_X) + "x" + String(MATRIX_PANELS_Y) + " P10 CLOCK";
|
||||
}
|
||||
|
||||
int textWidth = startMsg.length() * 6; // Approximation
|
||||
int startX = (TOTAL_WIDTH - textWidth) / 2;
|
||||
if (startX < 0) startX = 0;
|
||||
|
||||
display.setCursor(startX, 0);
|
||||
display.print(startMsg);
|
||||
|
||||
if (TOTAL_HEIGHT > 16) {
|
||||
display.setCursor(startX, 16);
|
||||
display.print("CASCADE MODE");
|
||||
} else {
|
||||
display.setCursor(startX, 8);
|
||||
display.print("READY");
|
||||
}
|
||||
|
||||
delay(3000);
|
||||
display.clearDisplay();
|
||||
|
||||
// Configuration WiFi
|
||||
if (useStationMode) {
|
||||
connecting_To_WiFi();
|
||||
if (!useStationMode) {
|
||||
set_ESP32_Access_Point();
|
||||
}
|
||||
} else {
|
||||
set_ESP32_Access_Point();
|
||||
}
|
||||
|
||||
// Démarrage du serveur web
|
||||
prepare_and_start_The_Server();
|
||||
|
||||
Serial.println("\nSetup completed. System ready!");
|
||||
|
||||
// Message de fin adapté à la configuration
|
||||
if (MATRIX_PANELS_X > 1) {
|
||||
Serial.printf("Running with %dx%d panels cascade (%dx%d total resolution)\n",
|
||||
MATRIX_PANELS_X, MATRIX_PANELS_Y, TOTAL_WIDTH, TOTAL_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Gestion du serveur web
|
||||
server.handleClient();
|
||||
|
||||
// Mise à jour de l'heure
|
||||
unsigned long currentMillis_Update_Time = millis();
|
||||
if (currentMillis_Update_Time - prevMill_Update_Time >= interval_Update_Time) {
|
||||
prevMill_Update_Time = currentMillis_Update_Time;
|
||||
get_Time();
|
||||
blink_Colon = !blink_Colon;
|
||||
}
|
||||
|
||||
// Affichage de l'horloge
|
||||
unsigned long currentMillis_Show_Clock = millis();
|
||||
if (currentMillis_Show_Clock - prevMill_Show_Clock >= interval_Show_Clock) {
|
||||
prevMill_Show_Clock = currentMillis_Show_Clock;
|
||||
|
||||
display.setTextSize(1);
|
||||
|
||||
// Couleur selon le mode
|
||||
if (input_Display_Mode == 1) {
|
||||
clock_Color = display.color565(Color_Clock_R, Color_Clock_G, Color_Clock_B);
|
||||
} else {
|
||||
clock_Color = myCOLOR_ARRAY[cnt_Color];
|
||||
}
|
||||
|
||||
// Calcul de la position centrée pour l'horloge (adapté à la largeur totale)
|
||||
int clock_width = 30; // Approximation pour "HH:MM"
|
||||
int clock_x = (TOTAL_WIDTH - clock_width) / 2;
|
||||
if (clock_x < 1) clock_x = 1;
|
||||
|
||||
// Effacer et afficher les heures
|
||||
if (last_minute_Val != minute_Val) display.fillRect(clock_x, 0, 11, 7, myBLACK);
|
||||
display.setTextColor(clock_Color);
|
||||
display.setCursor(clock_x, 0);
|
||||
display.print(chr_t_Hour);
|
||||
|
||||
// Position des deux points (centrée)
|
||||
int colon_x = clock_x + 14;
|
||||
if (blink_Colon) {
|
||||
drawColon(colon_x, 1, clock_Color);
|
||||
} else {
|
||||
drawColon(colon_x, 1, myBLACK);
|
||||
}
|
||||
|
||||
// Effacer et afficher les minutes
|
||||
if (last_minute_Val != minute_Val) display.fillRect(clock_x + 19, 0, 11, 7, myBLACK);
|
||||
display.setTextColor(clock_Color);
|
||||
display.setCursor(clock_x + 19, 0);
|
||||
display.print(chr_t_Minute);
|
||||
|
||||
last_minute_Val = minute_Val;
|
||||
}
|
||||
|
||||
// Gestion du texte défilant
|
||||
if (reset_Scrolling_Text) {
|
||||
start_Scroll_Text = false;
|
||||
set_up_Scrolling_Text_Length = true;
|
||||
reset_Scrolling_Text = false;
|
||||
}
|
||||
|
||||
if (start_Scroll_Text == false) {
|
||||
scrolling_text_Display_Order++;
|
||||
|
||||
if (input_Display_Mode == 1) {
|
||||
if (scrolling_text_Display_Order > 2) scrolling_text_Display_Order = 1;
|
||||
} else {
|
||||
if (scrolling_text_Display_Order > 3) scrolling_text_Display_Order = 1;
|
||||
}
|
||||
|
||||
// Affichage de la date
|
||||
if (scrolling_text_Display_Order == 1) {
|
||||
get_Date();
|
||||
display.setTextSize(1);
|
||||
scrolling_Y_Pos = 8;
|
||||
|
||||
if (input_Display_Mode == 1) {
|
||||
scrolling_Text_Color = display.color565(Color_Date_R, Color_Date_G, Color_Date_B);
|
||||
} else {
|
||||
int next_cnt_Color = (cnt_Color + 1) % myCOLOR_ARRAY_Length;
|
||||
scrolling_Text_Color = myCOLOR_ARRAY[next_cnt_Color];
|
||||
}
|
||||
|
||||
strcpy(text_Scrolling_Text, day_and_date_Text);
|
||||
}
|
||||
|
||||
// Affichage du texte personnalisé
|
||||
if (scrolling_text_Display_Order == 2) {
|
||||
display.setTextSize(1);
|
||||
scrolling_Y_Pos = 8;
|
||||
|
||||
if (input_Display_Mode == 1) {
|
||||
scrolling_Text_Color = display.color565(Color_Text_R, Color_Text_G, Color_Text_B);
|
||||
} else {
|
||||
int next_cnt_Color = (cnt_Color + 2) % myCOLOR_ARRAY_Length;
|
||||
scrolling_Text_Color = myCOLOR_ARRAY[next_cnt_Color];
|
||||
}
|
||||
|
||||
strcpy(text_Scrolling_Text, input_Scrolling_Text);
|
||||
}
|
||||
|
||||
// Changement de couleur (mode 2 seulement)
|
||||
if (scrolling_text_Display_Order == 3 && input_Display_Mode == 2) {
|
||||
cnt_Color = (cnt_Color + 1) % myCOLOR_ARRAY_Length;
|
||||
strcpy(text_Scrolling_Text, "");
|
||||
}
|
||||
|
||||
start_Scroll_Text = true;
|
||||
}
|
||||
|
||||
if (start_Scroll_Text) {
|
||||
run_Scrolling_Text(scrolling_Y_Pos, input_Scrolling_Speed, text_Scrolling_Text, scrolling_Text_Color);
|
||||
}
|
||||
|
||||
// Petit délai pour éviter la surcharge du processeur
|
||||
delay(1);
|
||||
}
|
||||
Reference in New Issue
Block a user