Hello,
I m struggling with LEDC and interruption.
I want to generate 2 PWM signals of 200 us and 116 us.
For each 1 in a byte I want to get a PWM signal of 200 ms with a duty of 50% when gpio RISING.
For each 0 in a byte I want to get a PWM signal of 116 us with 50% duty when GPIO rising.
To test my programme I m reading the byte 0b11011101111011011011 in the interruption function but it does not work. The output on the oscilloscope is constant and does not fit with what I want to get.
I have taken a resolution of 8 bits and a corresponding duty of 127 to get 50%.
Thanks for your help
#include "driver/ledc.h"
// setting PWM properties
#define sig_1_freq 8621 // fréquence de 116µs
#define sig_0_freq 5000 // fréquence de 200µs
const int pin_channel = 0; // choix du canan PWM0
const int sig_resolution = 8; // resolution = 1 bit pour 2 valeurs 0 et 1
const int sig_duty = 127; // pour le rapport cyclique de 1/2 1 bit => 1/2^1
uint32_t sig_freq = sig_0_freq; // On part de la fréquence 5000
#define CRAN_0 0
#define CRAN_1 1
#define CRAN_2 2
#define CRAN_IDLE 5
byte dccSpeed;
byte addr;
byte adresse;
byte vitesse;
byte cksum;
uint64_t v;
int msg; // 1 = marche;0 arret
const int dcc_pin = 19; // Sortie du signal DCC
const int pwn_pin = 18; // Sortie du signal DCC envoi courant
struct __attribute__((packed)) t_message { // total de 48 bits à envoyer
uint64_t stop: 1; // 1 bit à 1
uint64_t cksum: 8; // 8 bits de verification
uint64_t zero2: 1; // 1 bit à 0
uint64_t speeddir: 8; // 8 bits de direction et de vitesse
uint64_t zero1: 1; // 1 bit à 0
uint64_t address: 8; // 8 bits d'adresse
uint64_t start: 1; // 1 bit à 0
uint64_t debut: 20; // 20 bits à 1
};
void buildMessage(t_message& message, byte address, byte speedAndDir) {
message.debut = 0b11011101111011011011;
message.start = 0b0;
message.address = address;
message.zero1 = 0b0;
message.speeddir = speedAndDir;
message.zero2 = 0b0;
message.cksum = address ^ speedAndDir; // au hasard, prendre les bons octets
message.stop = 0b1;
dumpMessageBits(message);
}
t_message unMessage;
void dumpMessageBits(t_message& message) {
// int j=0;
//uint64_t v;
memcpy(&v, &message, sizeof v);
}
void setup() {
Serial.begin(115200);
pinMode(pwn_pin, OUTPUT);
ledcSetup(pin_channel,sig_freq, sig_resolution); // canal 0 frequence 5000 OU 8621 resolution 1 BIT 2 valeurs possibles 2^1=2
ledcAttachPin(dcc_pin, pin_channel); /// pin 19 au canal pwm O
ledcWrite(pin_channel,sig_duty);
attachInterrupt(dcc_pin, dcc_sig_isr, RISING); // a chaque fois que le signal est HIGH interruption se déclenche
}
void dcc_sig_isr() {
for (int i=19;i>=0;i--) {
if (bitRead(unMessage.debut,i)==1) {
sig_freq=sig_1_freq;
ledc_set_freq(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0, sig_freq);
}else{
sig_freq=sig_0_freq;
ledc_set_freq(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0, sig_freq);
}
}
}
// fonction de calcul 3 octets
void SpeedAndDir(byte addr, byte SelectCran, byte SelectSpeed, bool SelectDirection) // vecteur de direction et de vitesse
{
byte type;
byte ext;
byte dir;
byte cksum=0;
uint64_t paquet=0;
switch(SelectCran) {
case 0: ////DCC_PACKET_TYPE_STEP_14
dccSpeed=map(SelectSpeed,0,128,0,14);
if (dccSpeed) dccSpeed++; // pas de cran 1
dir=(SelectDirection?0x60:0x40)|dccSpeed;
break;
case 1: ///DCC_PACKET_TYPE_STEP_28
dccSpeed=map(SelectSpeed,0,128,0,28);
if (dccSpeed) dccSpeed+=3; // pas de cran 1,2,3
ext=(((dccSpeed&0x01)<<5)|dccSpeed)>>1; ///
dir=(SelectDirection?0x60:0x40)|ext;
break;
case 2: //DCC_PACKET_TYPE_STEP_128;
dccSpeed=map(SelectSpeed,0,128,0,126);
if (dccSpeed) dccSpeed++; // pas de cran 1
dir=(SelectDirection?0x60:0x40)|dccSpeed;
break;
case 5: //IDLE;
dir=0b00000000;
break;
}
buildMessage(unMessage, addr,dir);
}
void loop() {
SpeedAndDir(3, CRAN_1,101,1);
if (Serial.available() )
msg = Serial.parseInt(); // Lit le message reçu et l'affiche sur le moniteur
(msg)?digitalWrite(pwn_pin,HIGH):digitalWrite(pwn_pin,LOW);
//Serial.print(msg);
delay(500);
}