Re: Aquarium LED PWM Dimmer - Schaltzeiten (tank_control.pde)

Hallo, kann ich an Pin 9 einfach einen N-Channel Mosfet hängen, der die LED Stripes mit GND versorgt oder muss das ein extra PWM Regler sein?

Mich ärgert das sehr, daß man eine 4 Jahre alte Diskussion nimmt und eine andere Frage anhängt. War kurz davor den Post einfach zu löschen.

Dann zu allen Überfluß gibst Du keine brauchbaren Infos um Dir eine anständige Antwort zu geben.

Welche Art von Strip hast Du? Einen für 12V?

Grüße Uwe

Wird schon ein gewöhnlicher Stripe sein.... Da kommt es auf die Verschaltung an, nutzt Du es als Low-Side-Switch, geht ein N-Kanal-MOSFET. Brauchst Du aber einen High-Side-Switch, dann brauchst Du entweder eine entsprechende IC, oder einen P-Kanal-MOSFET, welcher mit einem Transistor angesteuert wird.

Sollten Dir die Begriffe High-Side bzw. Low-Side fremd sein, kurz Begriffe googeln und Du findest alles Nötige dazu ;)

Ich habe gestern noch einen richtiges PWM Modul dran gehangen, weil mit dem N-Mosfet dimmte das Licht nicht, sondern ging "hart" aus. Jetzt mit dem PWM Modul ist es aber leider genau so...... es schaltet hart aus....

http://www.aliexpress.com/item/3W-700mA-DC-DC-7-0-30V-to-1-2-28V-LED-lamp-Driver-Support-PWM/32436454701.html

Vin +12V Gnd alle miteinander verbunden PWM an den Arduino Pin 9

LED+ an den LED Stripe + (erstmal nur 50cm) LED- an LED Stripe GND

Ich nutze einen Nano 168 v3 mit microUSB, betreibe ihn aber über den VPin mit +12V.

Müsste doch laufen oder nicht?

Klingt stark nach nem Programmfehler, poste mal den Code.... vergiss `` nicht ;)

Sketch ist für IDE 0023

Ich habe den Code von Seite 1 genommen und mein Wassermelder hinzugepackt.
Ich habe eine Außenpumpe und wenn die leckt, soll der Wassermelder das erkennen, die Pumpe deaktivieren, eine LED und einen Buzzer bestromen. Das funktioniert auch ohne Probleme.
Und wie gesagt, der Timer zählt richtig, zur richtigen Zeit wird das Licht geschaltet, nur halt nicht gedimmt.

/*
 * Name:	tank_control.pde
 * Author:	User "sink" at plantedtank.net forums
 * URL:		http://bitbucket.org/akl/tank-control
 *
 * Aquariumlicht mit PWM Steuerung. Dimmt auf im Morgengrauen und dimmt ab zur Abenddämmerung
 * Die LED muss an einen PWM Pin! Beim Uno/Nano 3,5,6,9,10,11
 * 
 * Mit Wassersensor zum Deaktivieren der Pumpe im Notfall, mit Buzzer und LED...
 * 
 * 05.03.2016 V1
 * 06.04.2016 V2 + Mondlicht 
 */


const int Wassersensor = 3;                              // Wassersensor DPin 3 
const int WasserAus    = 4;                              // Ausgabe an Dpin 4
const int BUZZER       = 5;                              // Buzzer Dpin 5
const int LEDalarm     = 6;                              // LED Alarm an DPin 6
int WassersensorStatus = 0;                              // variable um den Wassersensor auszulesen






#include <TimerOne.h>
#include <Time.h>
#include <Wire.h>
#include <DS1307RTC.h>
//#include <DS3231RTC.h>

/*
 * IMPORTANT:  These *must* be the pins corresponding to the Timer1 timer on
 * the ATmega168/328.  These are digital pins 9 and 10 on the Uno/Duemilanove.
 */
const int kChan0Pin = 9; // Channel 0 Pin       Tageslicht
const int kChan1Pin = 10; // Channel 1 Pin      Mondlicht

// All times are in seconds since midnight (valid 0 - 86399)
const long kTurnOn = 32400; // time dawn begins - 0900hrs    32400 geteilt 3600 = 9
const long kTurnOff = 73800; // time sunset begins - 2030hrs

/*
 * Light "state" represents the PWM duty cycle for each channel This normally
 * dictates light intensity. It is an array { duty_chan_1, duty_chan_2 }.
 * Possible values for duty cycle are 0 - 1023.
 */
const int kDayState[] = { 900, 5 }; // daytime LED state      Taglicht soll mit 900 leuchten, Mondlicht mit 5
const int kNightState[] = { 0, 40 }; // nighttime LED state   Taglicht aus und Mondlicht bei 40

/*
 * Duration (in seconds) of fade. At the moment the only fades are sunrise and
 * sunset but this value will apply to any other fades you came up with
 */
const long kFadeDuration = 1800; // 30 minutes 

long ctr;

int state_chan1, state_chan2;

/*
 * fader -- Determine output state for a given time to provide smooth fade from
 * one state to another.
 *     Args:
 *     start_time  -- time (in seconds) of start of fade
 *     start_state -- beginning state
 *     end_state   -- ending state
 *     out         -- array to update with state
 */
void fader(long start_time, const int start_state[], const int end_state[], int out[2]) {

  float per_second_delta_0 = (float) (end_state[0]-start_state[0])/kFadeDuration;
  float per_second_delta_1 = (float) (end_state[1]-start_state[1])/kFadeDuration;

  long elapsed = ctr-start_time;

  out[0] = start_state[0] + per_second_delta_0 * elapsed;
  out[1] = start_state[1] + per_second_delta_1 * elapsed;
}

// return seconds elapsed since midnight
long seconds_since_midnight() {
  time_t t = now();
  long hr = hour(t);
  long min = minute(t);
  long sec = second(t);
  long total = hr * 3600 + min * 60 + sec;
  return total;
}

// set output state
void set_state(const int state[]) {
  if (state[0] >= 0 && state[0] <= 1023) {
    Timer1.setPwmDuty(kChan0Pin, state[0]);
    state_chan1 = state[0]; }
  if (state[1] >= 0 && state[1] <= 1023) {
    Timer1.setPwmDuty(kChan1Pin, state[1]);
    state_chan2 = state[1]; }
}

/*
 * determine_state -- This is where the actual timing logic resides.  We
 * examine ctr (seconds since midnight) and then set output state accordingly.
 * Variable ctr rolls back to 0 at midnight so stages that cross midnight (ie:
 * nighttime) are broken up into two stages.
 */
void determine_state() {
  if ( ctr >= 0 && ctr < kTurnOn ) { // night
      set_state(kNightState);
  } else if ( ctr >= kTurnOn && ctr <= (kTurnOn+kFadeDuration) ) { // sunrise
    int foo[2];
    fader(kTurnOn, kNightState, kDayState, foo);
    set_state(foo);
  } else if ( ctr > (kTurnOn+kFadeDuration) && ctr < kTurnOff ) { // day
    set_state(kDayState);
  } else if ( ctr >= kTurnOff && ctr <= (kTurnOff+kFadeDuration) ) { // sunset
    int foo[2];
    fader(kTurnOff, kDayState, kNightState, foo);
    set_state(foo);
  } else if ( ctr > (kTurnOff+kFadeDuration) && ctr < 86400 ) { // night
    set_state(kNightState);
  }
}

void printDigits(int digits) {
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void digitalClockDisplay() {
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(month());
  Serial.print("/");
  Serial.print(day());
  Serial.print("/");
  Serial.print(year()); 
  Serial.println(); 
}

void setup() {
  pinMode(Wassersensor, INPUT);          
  digitalWrite(Wassersensor, HIGH);       //Input Pullup!!!!!
  pinMode(LEDalarm, OUTPUT);
  pinMode(WasserAus, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  digitalWrite(LEDalarm, LOW);
  digitalWrite(WasserAus, LOW);
  digitalWrite(BUZZER, LOW);
  
  
  
  Serial.begin(115200); // Max for Arduino Uno
  setSyncProvider(RTC.get);
  Timer1.initialize(6666); // 150Hz PWM
  pinMode(kChan0Pin, OUTPUT);     
  Timer1.pwm(kChan0Pin, 0);
  pinMode(kChan1Pin, OUTPUT);     
  Timer1.pwm(kChan1Pin, 0);
}

void loop () {
  
  if (digitalRead(Wassersensor)==LOW){
        digitalWrite(LEDalarm, HIGH);
        digitalWrite(WasserAus, HIGH);                   // Auslösen wenn feucht
        digitalWrite(BUZZER, LOW);                       // Buzzer soll Alarm schlagen
       } else {
        digitalWrite(LEDalarm, LOW);
        digitalWrite(WasserAus, LOW);                    // nicht feucht -> nix tun
        digitalWrite(BUZZER, HIGH);                      // Buzzer soll nix tun
    }
  
  ctr = seconds_since_midnight();
  determine_state();

  if (Serial.available() >= 5) {
    char data[4];
    for (int i=0; i<5; i++) {
      data[i] = Serial.read();
    }

    Serial.flush(); // ensure we never have more than 5 bytes buffered

    if (data[0] == 'A') { // send current time
      time_t longInt = now();
      unsigned char byteArray[4];
                
      // convert from an unsigned long int to a 4-byte array
      byteArray[0] = (int)((longInt >> 24) & 0xFF);
      byteArray[1] = (int)((longInt >> 16) & 0xFF);
      byteArray[2] = (int)((longInt >> 8) & 0XFF);
      byteArray[3] = (int)((longInt & 0XFF));
      // send time
      Serial.print("Z");
      Serial.print(byteArray[0]);
      Serial.print(byteArray[1]);
      Serial.print(byteArray[2]);
      Serial.print(byteArray[3]);
    }
    else if (data[0] == 'B') { // set time
      union u_tag {
        byte b[4];
        unsigned long ulval;
      } u;

      u.b[0] = data[4];
      u.b[1] = data[3];
      u.b[2] = data[2];
      u.b[3] = data[1];

      RTC.set(u.ulval);
      setTime(u.ulval);
      Serial.print("Z0000");
    }
    else {
      Serial.print("X0000");
    }
  }

  delay(250);

/*
  Serial.print("ctr: ");
  Serial.print(ctr); // display counter
  Serial.println(); 
  Serial.print("channel 1, 2: "); 
  Serial.print(state_chan1); 
  Serial.print(", "); 
  Serial.print(state_chan2); 
  Serial.println(); 
  digitalClockDisplay(); //display time
  Serial.println(); 
*/
}

Du hast uns immer noch nicht geschrieben, was für ein Led-Stripe du einsetzt.

Der ist es....

Ja 12V. Und? Für was ist das ausschlaggebend?

Die PWM Steuerung dimmt übrigens auch ordentlich von "1024" auf meine eingestellten "900" herab, man sieht das schön nach dem Einschalten. Also das Modul selbst scheint seine Arbeit ordentlich zu verrichten, es muss in der Tat am Arduino/Sketch liegen.

Ich kann mir aber widerrum nicht vorstellen, dass es am Sketch liegt, denn im Forum wo ich den Sketch herhabe haben es ja sehr viele User schon genutzt. Ich habe auch dort eine Anfrage gestellt.

Ich teste jetzt mal einen anderen Arduino nur mit dem Original Sketch.

Ich würde mal ausgeben lassen, was er denn für PWM-Werte berechnet, also was in foo[] drin steht. Was aber auch auffällt: hast Du das delay(250) eingesetzt, oder stand das schon im Ausgangscode?

Ja das stand schon im Ausgangscode. Den hat uwefed ja leider zerfetzt.....