/*
Zinn-Dampfabzug Lötstation
Schwabenpilot.de - Buddinski88
Version 1.0
Basierend auf Scynd 2014
Link: http://we-mod-it.com/board258-diy-do-it-yourself/
board263-diy-how-to/board231-raspberry-arduino/
2522-arduino-tutorial-4-l%C3%BCfterdrehzal-auslesen/
*/
// Bibliotheken einbinden
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Fonts/FreeSansBoldOblique9pt7b.h>
// Konstanten
const int FanPin = 9; // Fan PIN D9
const int PotiPin = A1 ; // Potenziometer PIN A1
const int TachoPin = 2; // Tacho PIN D2
// Fan Symbol normal
const unsigned char PROGMEM fan [] = {
0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xE3, 0x87, 0xF3, 0xCF, 0x9F, 0xC1, 0xF3,
0xFF, 0x1F, 0xC2, 0x7F, 0xFC, 0x0F, 0xC3, 0xBF, 0xF8, 0x07, 0xC3, 0xDF, 0xF7, 0x03, 0xC3, 0xEF,
0xF7, 0xC3, 0xC7, 0xEF, 0xEF, 0xE3, 0xC7, 0xE7, 0xEF, 0xF7, 0xEF, 0xC7, 0xDF, 0xFF, 0xFF, 0x83,
0xD9, 0xFF, 0xFF, 0x03, 0xC0, 0x3F, 0xFC, 0x03, 0xC0, 0x3F, 0xFC, 0x1F, 0xC0, 0x7F, 0xFC, 0x7F,
0xC7, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFB, 0xDF, 0x9F, 0xF9, 0xFB,
0xDF, 0x1F, 0xF0, 0x03, 0xEE, 0x1F, 0xF8, 0x07, 0xEC, 0x1E, 0x7C, 0x07, 0xF4, 0x3E, 0x7E, 0x0F,
0xF0, 0x3E, 0x3F, 0xCF, 0xF8, 0x7E, 0x3F, 0xDF, 0xFC, 0x7E, 0x1F, 0xBF, 0xFE, 0x7E, 0x0E, 0x7F,
0xCF, 0xBF, 0x05, 0xFB, 0xCF, 0xE3, 0x07, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFE
};
// Fan Symbol rotiert
const unsigned char PROGMEM fan_rotiert [] = {
0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xD0, 0x47, 0xF3, 0xCF, 0xC0, 0xF9, 0xF3,
0xFE, 0x60, 0xFC, 0x7F, 0xFD, 0xF8, 0x7C, 0x3F, 0xFB, 0xF8, 0x7C, 0x3F, 0xF7, 0xFC, 0x7C, 0x3F,
0xF3, 0xFC, 0x7C, 0x2F, 0xE0, 0x7E, 0x78, 0x77, 0xE0, 0x1F, 0xF0, 0xFF, 0xC0, 0x1F, 0xF1, 0xFB,
0xCB, 0x1F, 0xFB, 0xFB, 0xFF, 0xFF, 0xFF, 0xFB, 0xDF, 0xFF, 0xFF, 0xF3, 0xFF, 0xFF, 0xFF, 0x81,
0xBF, 0xFF, 0xFC, 0x03, 0xDC, 0x3F, 0xFC, 0x03, 0xD8, 0x3F, 0xFE, 0x0B, 0xC0, 0x7F, 0xFF, 0xFB,
0xE0, 0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xEF, 0xFB, 0xE1, 0xF3, 0xC3, 0xF7, 0xF7, 0xE3, 0xE1, 0xEF,
0xF7, 0xE1, 0xE0, 0x6F, 0xFB, 0xE3, 0xF0, 0x1F, 0xFC, 0xE1, 0xF8, 0x3F, 0xFF, 0x61, 0xFC, 0xFF,
0xDF, 0xA1, 0xFD, 0xF3, 0xCF, 0xC0, 0xCF, 0xFB, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0xFF, 0xFF, 0xFE
};
// Variablen
int FanSpeed = 0; // Variable für die Lüftergeschwindigkeit
int FanMin = 50; // Minimaler PWM Wert für den Lüfter
int PotiVar = 0 ; // Variable zum speichern des Potentiometereingangs
int AbfrZeit = 500; // Zeitabstand für die Abfragen des Tachosignals
long TachoMillis = AbfrZeit; // Zeitabstand für Pulse Stretching Funktion
int DisplayAbfrZeit = 500; // Zeitabstand für die Abfragen des Tachosignals
long DisplayMillis = DisplayAbfrZeit; // Zeitabstand für Pulse Stretching Funktion
float RPS = 0; // Variable mit Kommastelle für die Berechnung der Umdrehungen pro Sekunde
int RPM = 0; // Variable für die gemittelte Drehzahl
float UmdrZeit = 0; // Variable mit Kommastelle für die Zeit pro Umdrehung des Lüfters
float FlankenZeit = 0; // Variable mit Kommastelle für die Zeit pro Puls des Lüfters
int FanSymbol = 0; // Entscheidung welches Symbol verwendet werden soll
// DIYMALL OLED spezifische Einstellungen
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
void setup() {
// Einmaliger Aufruf
TCCR1B = TCCR1B & 0b11111000 | 0x01; // Setzt Timer1 (Pin 9 und 10) auf 31300Hz
Serial.begin(9600);
//delay(3000);
pinMode(FanPin, OUTPUT) ; //Setzt den Lüfter Pin als Ausgang
pinMode(PotiPin, INPUT) ; //Setzt den LEDPin als Ausgang
pinMode(TachoPin, INPUT); //Setzt den Tacho Pin als Eingang
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
// Definiert die Schriftart
display.setFont(&FreeSansBoldOblique9pt7b);
// Bootlogo
display.setRotation(2);
display.display();
delay(4000);
// Leeren des Displays
display.clearDisplay();
}
void loop() {
// Mehrmaliger Aufruf
// Liest das Potentiometer aus
PotiVar = analogRead(PotiPin) ;
// Verteilt den PWM Wert über den Messbereich des Potis
FanSpeed = map(PotiVar, 50, 1023, FanMin, 255);
// Unterer Potenziometerbereichs (0-50) = Lüfter aus
if (PotiVar < 50) {
FanSpeed = 0;
}
analogWrite(FanPin, FanSpeed); // Gibt die Variable mit PWM aus
// Alle 2000ms pulse_stretch starten um die Drehzal auszulesen
if ((millis() - TachoMillis) >= AbfrZeit) {
pulse_stretch();
}
// Alle 1000ms pulse_stretch starten um die Drehzal auszulesen
if ((millis() - DisplayMillis) >= DisplayAbfrZeit) {
display_graphic();
}
display.display();
}
void pulse_stretch() {
// Nur wenn PotiVar größer als 50 ist, wird die RPM ausgelesen
if (PotiVar > 50) {
// Den Lüfter konstant mit Strom versorgen damit das Tachosignal funktioniert
analogWrite(FanPin, 255);
// Abfrage der Zeit pro Puls in Mikrosekunden
FlankenZeit = pulseIn(TachoPin, HIGH);
// Setzt die Lüftergeschwindigkeit zurück
analogWrite(FanPin, FanSpeed);
// Berechnung der Zeit pro Umdrehung in Millisekunden
UmdrZeit = ((FlankenZeit * 4) / 1000);
// Umrechnung auf Umdrehungen pro Sekunde
RPS = (1000 / UmdrZeit);
// Umrechnung auf Umdrehungen pro Minute
RPM = (RPS * 60);
// Ausgabe der Drehzahl im Seriellen Monitor
Serial.println(RPM);
// Zeigt die Umdrehungen an
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 58);
display.println(RPM);
}
// Wenn der Lüfter nicht angesteuert wird, schreibe Drehzahl 0
else {
// Drehzahl 0 in Seriellem Monitor ausgegeben
Serial.println("0");
}
// Die TachoMillis werden aktualisiert um die nächsten 2000ms zählen zu können
TachoMillis = millis();
}
// Funktion für das Display
void display_graphic() {
// Leert das Display
display.clearDisplay();
// Zeigt statischen Text an
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 16);
display.print("Drehzahl (rpm)");
if (PotiVar > 50) {
// Zeigt Umdrehungen an
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 58);
display.println(RPM);
// Entscheidung welches Symbol
if (FanSymbol == 0) {
//statisch
display.drawBitmap(94, 30, fan, 32, 32, WHITE);
FanSymbol = 1;
} else {
//rotiert
display.drawBitmap(94, 30, fan_rotiert, 32, 32, WHITE);
FanSymbol = 0;
}
} else {
// Zeigt die Umdrehungen auf dem Display an
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 58);
display.println("AUS");
display.drawBitmap(94, 30, fan, 32, 32, WHITE);
}
display.display();
}