Brauche Programmierhilfe Duemilanove

Hallo allerseits,

ich brauche Hilfe bei der Programmierung eines Duemilanove.
Ich hatte mal vor ein paar Jahren in der Schule mit Delphi programmiert,
aber mittlerweile hab ich wieder alles vergessen :disappointed_relieved:
Ich habe Folgendes mit dem Duemilanove vor:

2 unabhängige gebergeregelte PWM-Steuerungen mit Einflussmöglichkeit durch Schalter

Frage 1:
Mein E-Motor verfügt bereits über einen PWM Controller.
Den Controller muss ich mit 10HZ PWM Signalen füttern.
Kann man den Duemilanove auf 10Hz programmieren?

Frage 2:
Wie wird dem Due die Widerstandskennlinie eines Gebers beigebracht?
(wenn ich z.B. 3 Werte bei z.B. 60° 90° 120°ermittelt habe)

Frage 3:

Der 1. Steuerkreis soll grundsätzlich temperaturgeregelt laufen.
D.H. z.B.
<84° = 0%
85° - 87° = 30%
88° - 90° = 60%
91° - 94° = 80%

95° = 100%

Es sollen allerdings 4 Schalter die Temperaturregelung überschreiben können:
Wenn Schalter 1 und/ oder Schalter 2 “on”
<84° = 30%
85° - 87° = 50%
88°- 90° = 70%
91° - 94° = 90%

95° = 100%

Wenn Schalter 3 “on”
immer 100%

Wenn Schalter 4 “on”
immer 0%

Sind meine Anforderungen realisierbar?

Frage 4:

Der 2. Steuerkreis soll grundsätzlich druckgeregelt laufen.

Kann der Due einen Druckgeber auslesen
und daraus das benötigte PWM Signal für den Druckregler berechnen
um den programmierten Druck konstant zu halten?

Danke im Voraus!
Gruß Lena

Hi Lena willkommen,

hier mal ein paar kurze Antworten & Hinweise.

Antwort 1: http://lmgtfy.com/?q=arduino+change+pwm+frequency Antwort 2: Das wirst Du selbst programmieren müssen. Antwort 3: Ja Antwort 4: Der Arduino hat keinen eingebauten Drucksensor. Kann aber über die analogen Eingänge & weite Schnittstellen(I²C, Seriell, ...) gefüttert werden.

Bei konkreten weiteren Fragen gern melden.

Gruß

Sebastian

Hallo Sebastian,

vielen Dank für die schnelle Antwort. Leider bin ich aber noch nicht ganz schlau draus geworden.

Nochmal zu 1: So wie ich das verstanden habe, kann man die PWM Frequenz 31250/62500 nur durch die vorgegebenen Teiler von 1 bis 256 reduzieren?

Ich brauche exakt 10Hz. Ist das denn machbar, oder brauche ich da zusätzliche Bauteile?

Zu 4: Ich würde einen analogen Druckfühler anschliessen wollen und dann die Widerstandskennlinie dazu ausmessen und eintragen. Kann der Due das Signal auswerten und über PWM Modulation dann ein Ventil steuern, um den Druck konstant zu halten? Oder ist es eine Sisyphusarbeit, sowas zu programmieren?

Gruß Lena

Zu 1: Von http://usethearduino.blogspot.com/2008/11/changing-pwm-frequency-on-arduino.html

List of Possible Frequencies:

For pins 6 and 5 (OC0A and OC0B):

If TCCR0B = xxxxx001, frequency is 64kHz If TCCR0B = xxxxx010, frequency is 8 kHz If TCCR0B = xxxxx011, frequency is 1kHz (this is the default from the Diecimila bootloader) If TCCR0B = xxxxx100, frequency is 250Hz If TCCR0B = xxxxx101, frequency is 62.5 Hz

For pins 9, 10, 11 and 3 (OC1A, OC1B, OC2A, OC2B):

If TCCRnB = xxxxx001, frequency is 32kHz If TCCRnB = xxxxx010, frequency is 4 kHz If TCCRnB = xxxxx011, frequency is 500Hz (this is the default from the Diecimila bootloader) If TCCRnB = xxxxx100, frequency is 125Hz If TCCRnB = xxxxx101, frequency is 31.25 Hz

http://www.arduino.cc/playground/Code/PwmFrequency sagt:

  • The resulting frequency is equal to the base frequency divided by
  • the given divisor:
  • - Base frequencies:
  • o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
  • o The base frequency for pins 5 and 6 is 62500 Hz.
  • - Divisors:
  • o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
  • 256, and 1024.
  • o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
  • 128, 256, and 1024.

Die 10Hz sind ja nicht sehr viel. Das könnte man vermutlich "von Hand" schreiben. Also mit millis() arbeiten ohne die Arduino interne PWM Funktion.

Zu 4: Du erhältst dann Werte zwischen 0 und 1023 die einem Druck von x bis y bar entsprechen. Was Du damit machst ist allein durch deine Fantasie begrenzt.

Gruß

Sebastian

Hallo,

Slow-PWM - evtl. hilft dir das:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1266053553/4#4

...brauchte ich grad selber für eine Vollwellensteuerung....

Viele Grüsse, Michi

Hallo Sebastian,

das hört sich ja relativ human an. 10Hz heisst, ich hätte dann pro Periode 100 ms also 100 Abstufungen des "gefakten" PWM Signals.

Hallo Michi,

danke für den Link. Aber ich muss zugeben... Ich verstehe zwar, "was ich will" - aber mit der Programmiersprache komme ich absolut nicht zu Recht. Im Internet finde ich auch nur die Samples aus dem Arduino-Programm. Habt ihr vielleicht 'nen Link Tipp, wo es en Anfängr Tutorial auf Deutsch gibt? Oder komm ich um einen Buchakuf nicht rum?

Gruß Lena

@gatonero hatte sich mal die Mühe gemacht, das Lady Ada Tutorial zu übersetzen: http://www.freeduino.de/books/arduino-tutorial-lady-ada Eine kleine aber hilfreiche Übersicht gibt es dort auch: http://www.freeduino.de/books

Hallo,

ich habe jetzt mal versucht den 1. Steuerkreis zu programmieren.
Es ist aus diversen Modulen zusammengesetzt,
leider krieg ich den Code nicht mehr compiliert,
seit dem ich den Lookup Table eingebaut habe.
Vielleicht kann jemand mal mit einem wachsamen Auge drüberschauen
und mir helfen.

Dankeeeee
Grüße Lena

#include <avr/pgmspace.h>


/*==============================================================================
 * GLOBAL VARIABLES
 *============================================================================*/

//Variables:

int nextCall = HIGH;

int S1Pin = 0;             // Lüfterschalter
int S2Pin = 1;             // Druckschalter 
int S3Pin = 2;             // Schalter Zwangskühlung 
int S4Pin = 3;             // Schalter NOT-AUS
int TempSensorPin = A0;    // Wassertemperaturgeber

int tempval = 0; 
int s1 = 0;                //input Switch 1 
int s2 = 0;                //input Switch 2 
int s3 = 0;                //input Switch 3 
int s4 = 0;                //input Switch 4 
int fanval = 0;            //output % Wert Kühlgebläse

const int ledPin = 13;     // Pin PWM Ausgang an Kühlgebläse

unsigned long pmicros;

//Lookup Table for the VDOtemperature (22 Values) Its Calibration curve 92-027-006
//from -30C-180C in steps of 10C, the list is in 12Bit Digital Reading when supplyed with 5V and a 200Ohm Resistor in series 
//(measuring the Voltage on the Sensor)
//it has a decreasing Resistance with the Temperature
const unsigned int tempVDOTemp[] PROGMEM =
{ 
  4053,
  4019,
  3957,
  3857,
  3706,
  3497,
  3224,
  2893,
  2527,
  2150,
  1790,
  1471,
  1200,
  968,
  782,
  632,
  515,
  422,
  348,
  287,
  238,
  199
};







/*==============================================================================
 * SETUP()
 *============================================================================*/


void setup() 
{ 
  pinMode(ledPin, OUTPUT);    // sets the digital pin 13 as output 
  pinMode(S1Pin, INPUT);      // sets input pin 
  pinMode(S2Pin, INPUT);      // sets input pin 
  pinMode(S3Pin, INPUT);      // sets input pin 
  pinMode(S4Pin, INPUT);      // sets input pin 
} 







/*==============================================================================
 * LOOP()
 *============================================================================*/


void loop() 

//Converts the ADW Reading into °C
int GetVDOTemp(int ADWreading)
{
  int LookedupValue;
  //This searches the 2 surrounding values, and then linear interpolates between them.
  for(int i = 0; i<22;i++)
  {
   if(ADWreading <= pgm_read_word(&tempVDOTemp[i]) && ADWreading >= pgm_read_word(&tempVDOTemp[i+1]))
   {
    LookedupValue = (i*10) + 10 - ((10L *(ADWreading - pgm_read_word(&tempVDOTemp[i+1]))) / ((pgm_read_word(&tempVDOTemp[i]) - pgm_read_word(&tempVDOTemp[i+1]))));
    break;
   }
  }  
 
  LookedupValue -= 30;   //must be reduced as the lookup table starts at -30°C.
 
  LookedupValue = constrain(LookedupValue,-40,999);    //Limits the Output to 999°C, so an open circuit gets detectet!
  
  return LookedupValue;
}

{ 
  s1 = digitalRead(S1Pin);   // read input pin 
  s2 = digitalRead(S1Pin);   // read input pin 
  s3 = digitalRead(S1Pin);   // read input pin 
  s4 = digitalRead(S1Pin);   // read input pin 
  tempval = analogRead(TempSensorPin);   // read analog input 
  if (s4 = HIGH) 
  { 
    fanval = 0; 
  } 
  else 
  { 
    if (s3 = HIGH) 
    { 
      fanval = 100; 
    } 
    else 
    { 
      if (s1 == HIGH || s2 == HIGH) 
      { 
        if (tempval > 92) 
        { 
          fanval = 100; 
        } 
        else if (tempval > 87) 
        { 
          fanval = 80; 
        } 
        else if (tempval > 84) 
        { 
          fanval = 60; 
        } 
        else 
        { 
          fanval = 20; 
        } 
      } 
      else 
      { 
        if (tempval > 92) 
        { 
          fanval = 100; 
        } 
        else if (tempval > 87) 
        { 
          fanval = 60; 
        } 
        else if (tempval > 84) 
        { 
          fanval = 30; 
        } 
        else 
        { 
          fanval = 0; 
        } 
      } 
    } 
  } 

  Low_PWM(13,10,fanval);    //erster Wert AusgangsPin, Base Frequenz, Ontime 0-100%

} 



void Low_PWM (int ledpin, int Fre, int Value){
  long time;
  long ontime;
  time=1000000/Fre;
  ontime=time/100*Value;
  if (micros() - pmicros > time && nextCall==HIGH) {
    digitalWrite(ledpin,HIGH);
    pmicros=micros();
    nextCall=LOW;
  }
  if (micros() - pmicros > ontime&& nextCall==LOW){
    digitalWrite(ledpin,LOW);
    nextCall=HIGH;
  }
}