91
Vos projets / Re : Identification des trains par infrarouge
« Dernier message par CATPLUS le mai 10, 2025, 09:16:38 pm »Bonsoir Christophe
Bravo pour cette réalisation
Marcel
Bravo pour cette réalisation
Marcel
Le forum LOCODUINO est consacré aux discussions ayant trait à l'utilisation de l'Arduino dans les automatismes et les animations pour le train miniature. Nous avons eu récemment quelques inscriptions de personnes ayant des projets plus généraux mais surtout inapplicables au train miniature. Si votre projet ou vos questions ne concernent pas le modélisme ferroviaire, ne vous inscrivez pas, vous perdriez votre temps et nous aussi.
#include <Arduino.h>
#include "pico/multicore.h"
#include "pico/util/queue.h"
volatile uint32_t duration = 0;
constexpr byte pinIn = 15; // Broche du TSOP
bool receiving = false;
uint8_t currentByte = 0;
int8_t bitIndex = 7;
// File pour les bits détectés
queue_t durationQueue;
enum DecodeState {
IDLE,
RECEIVING
};
DecodeState currentState = IDLE;
void handleIR() {
static uint32_t lastTime = 0;
uint32_t now = micros();
uint32_t duration = now - lastTime;
lastTime = now;
queue_try_add(&durationQueue, &duration);
}
void setup() {
Serial.begin(115200);
pinMode(pinIn, INPUT);
// Initialisation de la queue pour 16 durées
queue_init(&durationQueue, sizeof(duration), 16);
attachInterrupt(digitalPinToInterrupt(pinIn), handleIR, RISING);
}
void loop() {
uint32_t duration = 0;
if (queue_try_remove(&durationQueue, &duration)) {
switch (currentState) {
case IDLE:
if (duration > 1600 && duration < 2400) {
// Début de trame détecté
currentByte = 0;
bitIndex = 7;
currentState = RECEIVING;
}
break;
case RECEIVING:
if (duration >= 400 && duration <= 700) {
// Bit 1
currentByte |= (1 << bitIndex);
bitIndex--;
} else if (duration >= 800 && duration <= 1200) {
// Bit 0
currentByte &= ~(1 << bitIndex);
bitIndex--;
} else {
// Durée invalide
currentState = IDLE;
break;
}
if (bitIndex < 0) {
Serial.printf("Octet reçu : 0x%02X\n", currentByte);
currentState = IDLE;
}
break;
}
}
}
```cpp
#include <Arduino.h>
// Configuration du timer pour PWM IR
#define IR_USE_AVR_TIMER2 // Utilise Timer2 pour l'envoi (pin D3)
#define SEND_PWM_BY_TIMER // Active le mode PWM matériel
#include "IRTimer.hpp" // Part of Arduino-IRremote https://github.com/Arduino-IRremote/Arduino-IRremote.
#define IR_SEND_PIN 3 // Broche utilisée
constexpr uint8_t DATA = 0xAA; // Octet à envoyer
constexpr uint16_t BIT_DURATION = 500; // Durée d’un bit en µs
// Envoie un octet codé via LED IR
void sendManchesterByte(uint8_t value) {
for (int i = 7; i >= 0; i--) {
bool bit = (value >> i) & 0x01;
if (bit) {
// 1
disableSendPWMByTimer(); delayMicroseconds(BIT_DURATION / 2);
enableSendPWMByTimer(); delayMicroseconds(BIT_DURATION / 2);
} else {
// 0
disableSendPWMByTimer(); delayMicroseconds(BIT_DURATION );
enableSendPWMByTimer(); delayMicroseconds(BIT_DURATION );
}
}
// Fin de trame
disableSendPWMByTimer();
delayMicroseconds(BIT_DURATION * 2);
enableSendPWMByTimer();
delayMicroseconds(BIT_DURATION * 2);
}
void setup() {
pinMode(IR_SEND_PIN, OUTPUT);
timerConfigForSend(38); // Fréquence IR : 38 kHz
disableSendPWMByTimer(); // Démarre éteint
}
void loop() {
sendManchesterByte(DATA);
}
```