NewAskSin Arduino Umbau von waitTimer auf Mikrosekunden für Lüftersteuerung

Begonnen von ahlermi, 15 März 2017, 15:37:09

Vorheriges Thema - Nächstes Thema

ahlermi

Hallo Zusammen,

hat jemand schon mal versucht die Klasse waitTimer auf Mikrosekunden umzubauen?

Das arbeiten mit   time = micros(); funktioniert leider nicht da die Variable immer überläuft.

Ich benötige den Timer aber um einen Lüfter mit PWM werten zu füttern.

Gruß Michael


class waitTimer {

  private: //---------------------------------------------------------------------------------------------------------
uint8_t  armed;
uint32_t checkTime;
uint32_t startTime;

  public: //---------------------------------------------------------------------------------------------------------
uint8_t  done(void);
void     set(uint32_t ms);
uint32_t remain(void);
};





/**
* @brief Query if the timer has expired
*
* @return 0 if timer is still running, 1 if not.
*         If the timer was never set(), return value is 1
*/
uint8_t  waitTimer::done(void) {
if (!armed) return 1; // not armed, so nothing to do
if ( (getMillis() - startTime) < checkTime ) return 0; // not ready yet

checkTime = armed = 0; // if we are here, timeout was happened, next loop status 1 will indicated
return 1;
}

/**
* @brief Start the timer
*
* @param ms Time until timer is done() (unit: ms)
*/
void     waitTimer::set(uint32_t ms) {
armed = ms?1:0;
if (armed) {
startTime = getMillis();
checkTime = ms;
}
}

/**
* @brief Query the remaing time until the timer is done
*
* @return Time until timer is done() (unit: ms)
*/
uint32_t waitTimer::remain(void) {
if (!armed) return 0;
return (checkTime - (getMillis() - startTime));
}

PI4 FHEM, PI3 FHEM, 6 x Echo mit talk2fhem, Siri, SNIPS auf PI3 mit Samson UB1, YeeLight, Homematic, MAX!, 433Mhz, LaCross, Xiaomi Vacuum V1, ESPEasy, Gardena, Telegram, FLOORPLAN, HEOS, Xiaomi Aqara, Sonoff, SolvisMax, SolvisClient, HUE, ESPEasy für Bayernlüfter, Harmony, Tasmota, JKBMS, EASUN

trilu

Hmmm, ich bin mir nicht sicher ob das Sinn macht. Die waittimer class wird ja gepollt, folglich ist das timing nicht sehr exakt. Im millisekunden Bereich ist das nicht weiter schlimm, wenn es im Programmablauf keine großen Verzögerungen kommt.
So wie ich Dich verstehe möchtest Du mikro Sekunden warten, zur Steuerung eines Lüfters...
Was genau möchtest Du erreichen, kannst Du mal beschreiben?

Ob Du mikros oder millis mißt, wird ja per Teiler im Timer entschieden, derzeit ist er halt auf millis eingestellt.
void init_millis_timer0(int16_t correct_ms) {
   timer = 0;
   power_timer0_enable();

   TCCR0A = _BV(WGM01);   // CTC mode - max 255
   TCCR0B = (_BV(CS01) | _BV(CS00));   // clk/64 (From prescaler)
   TIMSK0 = _BV(OCIE0A);
   OCR0A = ((F_CPU / 64) / 1000) + correct_ms;
}
CS01 und CS00 geben den Teilfaktor an. Es wird also der Systemtakt mit 64 geteilt
8.000.000 / 64 = 125.000 Hz
Der Timer Zähler wird also jede 1/125.000 Sekunde erhöht
und gegen OCR0A geprüft - 8.000.000 /64 /1000 = 125
Läuft also jede 1ms über - damit kannst du den Timer jetzt relativ einfach auf mikro sekunden umstricken, kommst aber garantiert mit dem Timing in Probleme.

papa

Geht denn kein Hardware PWM ? Zum Beispiel an Pin 3, der nutzt den internen Timer2. Wenn Du Adruino-API nimmst, einfach:


pinMode(3,OUTPUT);
analogWrite(3,0 - 255);

BananaPi + CUL868 + CUL433 + HM-UART + 1Wire

trilu

die kannst du doch auch mit der asksin verwenden?
der avr328 hat drei timer, timer0, timer1 und timer2
wenn du jetzt den pwm von timer2 verwenden willst musst du asksin halt sagen, dass sie timer0 oder timer1 für die getmillis() funktion verwenden soll.
der asksin sagst du das mit    

init_millis_timer0();                                                   // init timer0

im user sketch setup

schau dir mal den dimmer sketch an, da nutze ich auch den pwm

ahlermi

Danke schon mal für die Rückmeldungen!

Mir geht es darum eine Belüftung über "Homematic" zu steuern, sprich PC Lüfter bestimmt schnell laufen zu lassen.

Im besten Fall sende ich dann sogar zurück wie schnell der Lüfter wirklich gerade läuft.

Beispiel:
https://www.frag-duino.de/index.php/maker-faq/41-steuerung-eines-4-pin-cpu-luefters-mit-arduino

In dem Beispiel wird ein Signal an den Lüfter geschickt 100001000010000..... das immer Low und High im Abstand von x Microsekunden. Ein Delay kommt natürlich nicht in Frage.

/* -------------------------------------------
/* CPU-Lüfter Steuern und messen
/* www.frag-duino.de
/* -------------------------------------------
/* Befehle:
/* 0-10 --> Länge des HIGH-Signals in ms*10
/* Langsam nach schnell: 1,2,3,4,5,6,7,8,9
/* 0 fuer STOP
------------------------------------------- */

// PINs
#define PIN_BLAU 6
#define PIN_YELLOW 2
#define INTERRUPT_GELB 0  // Interrupt 0 == Pin 2
#define UPDATE_ZYKLUS 1000 // Jede Sekunde 1 ms Ausgabe der Geschwindigkeit.
const int ANZAHL_INTERRUPTS = 1; // Anzahl der Interrupts pro Umdrehung (1 oder 2)

// Variablen
int counter_rpm = 0;
int rpm = 0;
unsigned long letzte_ausgabe = 0;
char eingabe;
int dauer_low = 1;
int dauer_high = 9;
int baseTime = 10; // Insgesamt 10 ms

void setup()
{
  // Initialisieren
  Serial.begin(9600);
  pinMode(PIN_BLAU, OUTPUT);
    pinMode(PIN_YELLOW, INPUT);
  digitalWrite(PIN_YELLOW, HIGH);
  attachInterrupt(INTERRUPT_GELB, rpm_fan, FALLING);
}

void loop(){

  if(dauer_low * 10 != 0){
    digitalWrite(PIN_BLAU, LOW);
    delayMicroseconds(dauer_low * 10);
  }

  if(dauer_high * 10 != 0){
    digitalWrite(PIN_BLAU, HIGH);
    delayMicroseconds(dauer_high * 10);
  }

  if (Serial.available()){
    eingabe = Serial.read() - 48; // ASCII 0-9 lesen
    if(eingabe == 0)
      eingabe = 10;
    else
      eingabe = 10 - eingabe;

    dauer_low = eingabe;
    dauer_high = baseTime - eingabe;
    Serial.print("Dauer des HIGH: ");
    Serial.println(dauer_high);
  }

  if (millis() - letzte_ausgabe >= UPDATE_ZYKLUS){
    // Interrupt deaktivieren um das rechnen nicht zu unterbrechen.
    detachInterrupt(0);

    // RPM errechnen und ausgeben:
    rpm = counter_rpm * (60 / ANZAHL_INTERRUPTS);
    Serial.print("RPM: ");
    Serial.println(rpm);

    // Counter zuruecksetzen
    counter_rpm = 0;

    // Zeitpunkt setzen
    letzte_ausgabe = millis();

    // Interrupt wieder aktivieren
    attachInterrupt(0, rpm_fan, FALLING);
  }
}


// Interrupt zaehlt den RPM-Counter hoch
void rpm_fan(){
  counter_rpm++;
}



Oder kann ich alternativ sowas im NewAskSin nutzen?

http://we-mod-it.com/board258-diy-do-it-yourself/board263-diy-how-to/board231-raspberry-arduino/2458-arduino-tutorial-3-l%C3%BCfter-per-pwm-steuern/?s=e8efaac3d39e7600492e1f811a2db23ec516a22e

/*
Arduino Tutorial 3.2 - Lüftergeschwindigkeit per Taster wechseln

by Scynd 2014

In diesem Tutorial geht es darum die Geschindigkeit eines Lüfters
per tastendruck um einen vordefinierten Wert zu erhöhen oder zu senken.

*/


// Konstante Variablen

const int FanPin = 9; // Pin für den Lüfter

// Variablen

int Schrittweite = 20; // Variable für die Schrittweite pro Tasterdruck des PWM Wertes
int FanSpeed = 75; // PWM Startwert des Lüfters (ca.30%)

void setup() {

TCCR1B = TCCR1B & 0b11111000 | 0x01; // Setzt Timer1 (Pin 9 und 10) auf 31300Hz

pinMode(FanPin, OUTPUT); // Setzt den Pin des Lüfters als Ausgang

/* Der Lüfter bekommt 1 Sekunde einen Startimpuls und wir dann gedrosselt.
Das ist eine Sicherheitsmaßnahme, falls der Lüfter mit 30% nicht anläuft
*/
analogWrite(FanPin, 255);
delay(1000);
analogWrite(FanPin, FanSpeed);
}


void loop() {


// Der ausgegebene PWM Wert wird auf den Bereich 75-255 begrenzt
if(FanSpeed > 255) {
FanSpeed = 255;
}

if(FanSpeed < 75) {
FanSpeed = 75;
}

analogWrite(FanPin, FanSpeed); // Gibt den PWM Wert am FanPin aus
}


Für mich ist das mit dem Timings leider ziemlich neu, ich komme eigentlich aus der SAP / VisualBasic Welt.

Gruß Michael
PI4 FHEM, PI3 FHEM, 6 x Echo mit talk2fhem, Siri, SNIPS auf PI3 mit Samson UB1, YeeLight, Homematic, MAX!, 433Mhz, LaCross, Xiaomi Vacuum V1, ESPEasy, Gardena, Telegram, FLOORPLAN, HEOS, Xiaomi Aqara, Sonoff, SolvisMax, SolvisClient, HUE, ESPEasy für Bayernlüfter, Harmony, Tasmota, JKBMS, EASUN

trilu

eigentlich gibts das doch schon, ein dimmer ist doch genau das was du willst?
es wird halt nicht das licht heller oder dunkler, sondern es dreht sich der lüfter schneller oder langsamer.
schau dir mal das dimmer beispiel an...