====== 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 #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); } * [[wiki:projets:smartphone-geiger:internal_voltage|Article suivant : mesure précise de tension]] * [[wiki:projets:smartphone-geiger:accueil|Retour à l'accueil]] * [[wiki:projets:smartphone-geiger:chronologie|Retour à la chronologie du projet]] * [[wiki:projets:smartphone-geiger:comptage-leds|Article précédent : gestion des LEDs]]