Modification de la fréquence du PWM

Pour générer la haute tension, il ne suffit pas de modifier le rapport cyclique du PWM : ceci permet de régler la haute tension, mais pour que la haute tension apparaisse, il faut ajuster la fréquence du PWM selon les composants inductifs utilisés (self ou transformateur).

#include <RFduinoBLE.h>
#include "Adafruit_NeoPixel.h"
 
#define FREQ 1000
 
int count = 0;
int pwmValue = 0;
 
int isCo = 0;
 
long precTime;
 
Adafruit_NeoPixel strip = Adafruit_NeoPixel(3, 6, NEO_GRB + NEO_KHZ800);
 
void TIMER1_INTERUPT(void) {
  if (NRF_TIMER1->EVENTS_COMPARE[0] != 0) {
    digitalWrite(2, LOW);
    digitalWrite(3, LOW);
    NRF_TIMER1->EVENTS_COMPARE[0] = 0;
 
    NRF_TIMER2->TASKS_START = 1; // Redemarre le timer
    NRF_TIMER1->TASKS_STOP = 1; // Arrete le timer
  }
}
 
void TIMER2_INTERUPT(void) {
  if (NRF_TIMER2->EVENTS_COMPARE[0] != 0) {
    digitalWrite(2, HIGH);
    digitalWrite(3, HIGH);
    NRF_TIMER2->EVENTS_COMPARE[0] = 0;
 
    NRF_TIMER1->TASKS_START = 1; // Redemarre le timer
    NRF_TIMER2->TASKS_STOP = 1; // Arrete le timer  
  }
}
 
void configTimer(NRF_TIMER_Type* nrf_timer, IRQn_Type irqn, callback_t callback, float duty_c) {
  nrf_timer->TASKS_STOP = 1; // Arrete le timer
  nrf_timer->MODE = TIMER_MODE_MODE_Timer;
  nrf_timer->BITMODE = (TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos);
  nrf_timer->PRESCALER = 4; // résolution de 1 usec
  nrf_timer->TASKS_CLEAR = 1;
  nrf_timer->CC[0] = FREQ * duty_c;
  nrf_timer->INTENSET = TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos;
  nrf_timer->SHORTS = (TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos);
  attachInterrupt(irqn, callback);
  nrf_timer->TASKS_START = 1; // Redemarre le timer
}
 
int countCallback(uint32_t ulPin) {
  count++;
 
  strip.setPixelColor(2, strip.Color(255, 255, 255)); // Flash geiger
  strip.show();
  delay(50);
  strip.setPixelColor(2, strip.Color(0, 0, 0));
  strip.show();
  return 0;
}
 
void setup() {  
  pinMode(2, OUTPUT); // Les pins 2 et 3 sont utilisées pour
  pinMode(3, OUTPUT); // controler la haute tension
 
  configTimer(NRF_TIMER1, TIMER1_IRQn, TIMER1_INTERUPT, 0.2);
  configTimer(NRF_TIMER2, TIMER2_IRQn, TIMER2_INTERUPT, 0.8);
 
  strip.begin();
  strip.show();
 
  strip.setBrightness(32); 
  strip.setPixelColor(0, strip.Color(0, 255, 0)); // Etat de batterie
  strip.show();
 
  pinMode(4, INPUT); // La pin 4 compte les impulsions du tube
  RFduino_pinWakeCallback(4, LOW, countCallback);
 
  RFduinoBLE.deviceName = "OpenGeiger"; // Le nom et la description doivent faire
  RFduinoBLE.advertisementData = ""; // moins de 18 octets en tout.
 
  RFduinoBLE.begin();
 
  precTime = millis();
}
 
void loop() {
 if (millis() - precTime > 10000) {
   // Toutes les 10 secondes, on envoi le comptage au smartphone
   RFduinoBLE.sendInt(count);
 
   precTime = millis();
   count = 0;
 }
}
 
void RFduinoBLE_onConnect() {
  isCo = 1; // Un smartphone s'est connecté
  strip.setPixelColor(1, strip.Color(0, 0, 255)); // Etat bluetooth
  strip.show();
}
 
void RFduinoBLE_onDisconnect() {
 isCo = 0; // Un smartphone s'est déconnecté
 strip.setPixelColor(1, strip.Color(0, 0, 0));
 strip.show();
}
 
int getInt(char*data, int len) {
  int value=0;
  int p=1;
  for (int i=len-1 ; i>=0 ; i--) {
    value += p*(data[i]-'0');
    p*=10;
  }
  return value;
}
 
void RFduinoBLE_onReceive(char *data, int len) {
  pwmValue = getInt(data, len);
  float v = pwmValue / 100.0;
  configTimer(NRF_TIMER1, TIMER1_IRQn, TIMER1_INTERUPT, v);
  configTimer(NRF_TIMER2, TIMER2_IRQn, TIMER2_INTERUPT, 1.0-v);
}