Schlagwort-Archive: Arduino

BitBastelei #247 – PC-Lüfter per Arduino auslesen und steuern

BitBastelei #247 - PC-Lüfter per Arduino auslesen und steuern

(81 MB) 00:19:34

2017-07-16 10:00 🛈

Lüfter sind laut und nervig – aber auch nicht so ganz unwichtig. Praktischerweise kann man PC-Lüfter recht einfach selbst nutzen. Schauen wir mal, welche Arten von Lüftern es so gibt und wie man diese per Arduino auslesen und steuern kann.

Korrekturen & Hinweise

  • 10:58 OZI und Arduino haben über USB den selben GND
  • 13:22 FALLING wäre bei diesem Signal besser
  • 16:25 Laut Spezifikation sind 21-28kHz zulässig

Links zum Thema

Code

unsigned long last1 = 0;
unsigned long last2 = 0;
unsigned long lasts = 0;
unsigned int dur1 = 0;
unsigned int dur2 = 0;
byte tgt1 = 128;
byte tgt2 = 128;

void setup() {
  Serial.begin(115200);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(2), tacho1, FALLING);
  attachInterrupt(digitalPinToInterrupt(3), tacho2, FALLING);

  //Timer 1: Prescaler 0
  TCCR1B = TCCR1B & B11111000 | B00000001;

  analogWrite(9, 128);
  analogWrite(10, 128);
}

void getPwm(byte &val) {
  byte tmp = Serial.parseInt();
  if(tmp > 0) val = map(tmp, 0, 100, 0, 255);
}

void loop() {
  unsigned long cm = millis();

  if(Serial.available()) {
    byte tmp = Serial.parseInt();
    switch(tmp) {
      case 1:
        getPwm(tgt1);
        break;
      case 2:
        getPwm(tgt2);
        break;
    }
  }
  
  if(lasts > cm || (lasts + 1000) < cm) {
    digitalWrite(13, !digitalRead(13));
    Serial.print("Delay1: ");
    Serial.print(dur1);
    Serial.println("µs");

    unsigned long freq = 100000000 / dur1;
    Serial.print("Frequenz1: ");
    Serial.print(freq/100);
    Serial.print('.');
    Serial.print(freq%100);
    Serial.println("Hz");

    freq *= 60;
    freq /= 200;
    Serial.print("RPM1: ");
    Serial.println(freq);

    
    Serial.print("Ziel1: ");
    Serial.print(map(tgt1, 0, 255, 0, 100));
    Serial.println('%');

    
    Serial.print("Delay2: ");
    Serial.print(dur2);
    Serial.println("µs");

    freq = 100000000 / dur2;
    Serial.print("Frequenz2: ");
    Serial.print(freq/100);
    Serial.print('.');
    Serial.print(freq%100);
    Serial.println("Hz");

    freq *= 60;
    freq /= 200;
    Serial.print("RPM2: ");
    Serial.println(freq);

    
    Serial.print("Ziel2: ");
    Serial.print(map(tgt2, 0, 255, 0, 100));
    Serial.println('%');
    
    Serial.println("-----");
    lasts = millis();
  }

  analogWrite(9, tgt1);
  analogWrite(10, tgt2);
}

void tacho1() {
  unsigned long cm = micros();
  dur1 = (cm - last1);
  last1 = cm;
}

void tacho2() {
  unsigned long cm = micros();
  dur2 = (cm - last2);
  last2 = cm;
}

BitBastelei #245f – Haussteuerung mit CAN und Arduino: IO-Module

BitBastelei #245f - Haussteuerung mit CAN und Arduino: IO-Module

(24 MB) 00:10:07

2017-07-02 11:02 🛈

Die vermutlich komplexeste, aber auch leistungsfähigste Variante in aSysBus: IO-Module. Hierbei werden nicht mehr separate Funktionen geschrieben, sondern nur noch Konfigurationen für Adressen und Pins vergeben. Diese werden im EEPROM abgelegt und können – ganz ohne dem Arduino neu zu programmieren – im Betrieb geändert werden.

CAN-Bus-Library:
https://github.com/adlerweb/CAN_BUS_Shield
aSysBus-Library:
https://github.com/adlerweb/aSysBus

BitBastelei #245e – Haussteuerung mit CAN und Arduino: Eigene Funktionen anbinden

BitBastelei #245e - Haussteuerung mit CAN und Arduino: Eigene Funktionen anbinden

(14 MB) 00:08:05

2017-07-02 11:01 🛈

Über „Hooks“ kann man in aSysBus eigene Funktionen mit einem Filter verbinden. Statt selbst das aussortieren der Pakete programmieren zu müssen kann man hier diese Aufgabe der Library übertragen. Trifft später ein Paket ein, welches den angegebenen Daten entspricht, wird die eigene Funktion aufgerufen.

CAN-Bus-Library:
https://github.com/adlerweb/CAN_BUS_Shield
aSysBus-Library:
https://github.com/adlerweb/aSysBus

BitBastelei #245d – Haussteuerung mit CAN und Arduino: Einfacher Knoten

BitBastelei #245d - Haussteuerung mit CAN und Arduino: Einfacher Knoten

(15 MB) 00:09:45

2017-07-02 11:00 🛈

Jetzt geht es ans programmieren: Die Variante „simple“ beschränkt sich auf das nötigste: Den Knoten online bringen, Pakete senden und Empfangen. Programmlogik kann man mit wenigen Befehlen in Arduino selbst entwickeln. Diese Methode eignet sich daher für alle, welche individuelle Steuerungen bauen.

CAN-Bus-Library:
https://github.com/adlerweb/CAN_BUS_Shield
aSysBus-Library:
https://github.com/adlerweb/aSysBus

BitBastelei #245c – Haussteuerung mit CAN und Arduino: Installation & Hardware

BitBastelei #245c - Haussteuerung mit CAN und Arduino: Installation & Hardware

(24 MB) 00:05:43

2017-07-02 10:31 🛈

Selbst eine Haussteuerung mit Arduino bauen? Kein Problem. Hier schauen wir wie wir die nötigen Libraries installieren und für wenig Geld passende Hardware zusammenstecken können.

CAN-Bus-Library:
https://github.com/adlerweb/CAN_BUS_Shield
aSysBus-Library:
https://github.com/adlerweb/aSysBus

Bild: https://www.adlerweb.info/blog/wp-content/uploads/2017/07/mcparduino-300×169.png

BitBastelei #245b – Haussteuerung mit CAN und Arduino: Der aSysBus

BitBastelei #245b - Haussteuerung mit CAN und Arduino: Der aSysBus

(19 MB) 00:09:21

2017-07-02 10:30 🛈

Nach langem Gebastel ist er da: Der Arduino System Bus (aSysBus). Schauen wir mal, was dahinter steckt, wie die Library aufgebaut ist und was alles unterstützt wird.

CAN-Bus-Library:
https://github.com/adlerweb/CAN_BUS_Shield
https://github.com/Seeed-Studio/CAN_BUS_Shield
aSysBus-Library:
https://github.com/adlerweb/aSysBus

BitBastelei #245a – Haussteuerung mit CAN und Arduino: Was ist Haussteuerung?

BitBastelei #245a - Haussteuerung mit CAN und Arduino: Was ist Haussteuerung?

(23 MB) 00:10:23

2017-07-02 10:00 🛈

Nach langer Zeit geht es mal wieder um Haussteuerung: Ich habe mein System nun soweit auf Arduino portiert und online gestellt. Aber schauen wir erst mal was überhaupt Haussteuerung ist, warum man eine solche haben möchte, was dagegen spricht und welche Konzepte es gibt.

[ICStation.com] BitBastelei #243 – Si1145 Licht/IR/UV-Sensor

[ICStation.com] BitBastelei #243 - Si1145 Licht/IR/UV-Sensor

(107 MB) 00:24:19

2017-06-18 10:00 🛈

Sensorzeit: Mit dem Si1145 lassen sich so einige Werte aus dem Bereich „Licht“ erfassen: Neben der sichtbaren Lichtstärke rückt der Sensor gleich noch den Infrarot-Anteil und den aktuellen UV-Index raus. Praktisch wenn man wissen möchte, wie schnell der Sonnenbrand droht. Alles läuft mittels I²C, lässt sich also schnell mit nahezu jedem Mikrocontroller auswerten.

Das Modul von ICStation.com bringt den 2x2mm-Winzling auf ein für Bastler brauchbares Format und sorgt auch gleich noch dafür, dass die 5V eines Arduino den 3.3V-Chip nicht gleich zerstören.

Inhalt

  • 00:00 IC und Modul
  • 07:09 Si1145 an Arduino
  • 12:32 Messwerte – Si1145 vs. offizielle Werte
  • 17:07 Si1145 an ESP8266

Produkt

http://www.icstation.com/si1145-integrated-infrared-ultraviolet-sensor-module-arduino-stm32-p-10572.html

Mit dem Rabattcode: bitics gibt es 15% Rabatt

Korrekturen

Arduino betreibt die I²C-Pins immer mit internem Pull-Up, bei Nutzung eines 5V-Arduinos besteht daher die Gefahr, dass der Sensor beschädigt wird. Es sollte ein „I²C-Level-Shifter“ oder 3.3V-Mikrocontroller (3.3V-Arduino, ESP8266, etc) genutzt werden!

Weitere Links

Bild: https://www.adlerweb.info/blog/wp-content/uploads/2017/06/arduino-si1145-300×169.png

BitBastelei #236 – Arduino-Temperaturmessung mit Thermoelement & MAX6675

BitBastelei #236 - Arduino-Temperaturmessung mit Thermoelement & MAX6675

(68 MB) 00:13:55

2017-03-26 10:00 🛈

Üblicherweise nutze ich für Temperaturmessungen den DS18B20, einen 1Wire-Sensor, welcher die Temperatur digital an den genutzten Mikrocontroller übermittelt. Hat man jedoch mit höheren Temperaturen zu tun muss man sich etwas anderes suchen: Maximal 80°C sind in guter Genauigkeit möglich. Wer in heißeren Umgebungen spielt kann z.B. ein K-Thermoelement nutzen, welches vielen von ihrem Multimeter bekannt sein dürfte. Zusammen mit einem MAX6675 lassen sich auch diese einfach an Controllern nutzen.

Als Beispiel verbinde ich ein solches Thermoelement mit MAX6675, einem Arduino und einem OLED-Display um die Temperatur eines Backofens im Auge zu behalten – und das genauer als das Original-Thermostat.

Links:

BitBastelei #234 – WS2812B (Neopixel) Uhr

BitBastelei #234 - WS2812B (Neopixel) Uhr

(132 MB) 00:38:13

2017-03-12 11:00 🛈

Die WS2812B, auch bekannt als Neopixel, sind RGB-LEDs mit internem Steuer-IC, welche sich über einen einzelnen Datenpin kaskadieren und separat ansteuern lassen. Als in meinem Feed ein Angebot für ¼-Kreise mit 15 dieser LEDs durchtickerte war der Plan schnell klar: 4 ¼-Kreise á 15 LEDs macht 60 LEDs. Passend für eine Uhr. Mal schauen, ob es auch funktioniert.
Zur Zeithaltung kommt ein DS3231 zum Einsatz – ein I²C-Chip, welcher speziell für Uhren gedacht ist und genauer funktioniert als die internen Taktgeber der üblichen µCs.

Inhalt:

  • 00:00 LED-Module & Aufbauplan
  • 08:22 LED-Test mit Adafruit-Library
  • 12:32 Warum RTC statt Systemtakt / millis()?
  • 17:05 Blick auf die Software
  • 34:13 Uhr in Aktion

Code:

/**
 * NeoClock
 * 
 * Clock using 60 WS2812B/Neopixel LEDs and DS3231 RTC
 * 
 * Libraries needed:
 *   * Adafruit NeoPixel (Library Manager) - Phil Burgess / Paint Your Dragon for Adafruit Industries - LGPL3
 *   * Rtc by Makuna (Library Manager) - Michael C. Miller
 *   * Arduino Timezone Library (https://github.com/JChristensen/Timezone) - Jack Christensen - CC-BY-SA
 *   * Time Library (https://github.com/PaulStoffregen/Time) - Paul Stoffregen, Michael Margolis - LGPL2.1
 */

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
  #include <avr/power.h>
#endif

#if defined(ESP8266)
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif

#include <SoftwareWire.h>  // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>

#include <Time.h>        //http://www.arduino.cc/playground/Code/Time
#include <Timezone.h>    //https://github.com/JChristensen/Timezone

#include <EEPROM.h>

//Central European Time (Frankfurt, Paris)
TimeChangeRule CEST = {"CEST", Last, Sun, Mar, 2, 120};     //Central European Summer Time
TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60};       //Central European Standard Time
Timezone CE(CEST, CET);

TimeChangeRule *tcr;        //pointer to the time change rule, use to get the TZ abbrev
time_t utc;

SoftwareWire myWire(8, 9);
RtcDS3231<SoftwareWire> Rtc(myWire);

#define PIN 6

unsigned long lastMillis = millis();
byte dimmer = 0x88;
byte hmark = 0;

byte ohour=0;
byte ominute=0;
byte osecond=0;

boolean fader=true;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);

void setup() {

  Serial.begin(115200);
  
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'

  Rtc.Begin();

  Rtc.Enable32kHzPin(false);
  Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone); 

  if (!Rtc.GetIsRunning())
  {
      Serial.println("RTC was not actively running, starting now");
      Rtc.SetIsRunning(true);
  }

  if (!Rtc.IsDateTimeValid()) 
  {
      // Common Cuases:
      //    1) the battery on the device is low or even missing and the power line was disconnected
      Serial.println("RTC lost confidence in the DateTime!");
  }

  byte eechk = EEPROM.read(0);
  if(eechk == 0xAA) { //Assume this is our config and not a fresh chip
    dimmer = EEPROM.read(1);
    hmark = EEPROM.read(2);
    fader = EEPROM.read(3);
  }

  timeSync();
}

void calcTime(void) {
  utc = now();
  CE.toLocal(utc, &tcr);
  ohour = hour(utc);
  ominute = minute(utc);
  if(osecond != second(utc)) {
    osecond = second(utc);
    lastMillis = millis();

    if(ominute == 0 && osecond == 0) {
      //Every hour
      timeSync();
    }
  }
}

void addPixelColor(byte pixel, byte color, byte brightness) {
  color *= 8;
  uint32_t acolor = brightness;
  acolor <<= color;
  uint32_t ocolor = strip.getPixelColor(pixel);
  ocolor |= acolor;
  strip.setPixelColor(pixel, ocolor);
}

void drawClock(byte h, byte m, byte s) {  
  strip.clear();
  
  addPixelColor(m, 1, dimmer);

  if(hmark > 0) {
    for(byte i = 0; i<12; i++) {
      addPixelColor((5*i), 2, hmark);
    }
  }

  h %= 12;
  h *= 5;
  h += (m/12);
  addPixelColor(h, 2, dimmer);
  // 0x RR GG BB

  if(fader) {
    byte dim_s1 = dimmer;
    byte dim_s2 = 0;
    byte px_s2 = s+1;
    if(px_s2 >= 60) px_s2 = 0;
    unsigned long curMillis = millis()-lastMillis;
    if(curMillis < 250) {
      dim_s2 = 0;
      dim_s1 = dimmer;
    }else{
      dim_s2 = map(curMillis, 250, 1000, 0, dimmer);
      dim_s1 = dimmer - map(curMillis, 250, 1000, 0, dimmer);
    }
    
    addPixelColor(s, 0, dim_s1);
    addPixelColor(px_s2, 0, dim_s2);
  }else{
    addPixelColor(s, 0, dimmer);
  }
  
  strip.show();
}

byte rounds = 0;

void loop() {
  calcTime();

  if(rounds++ > 100) {
    Serial.print(ohour);
    Serial.print(":");
    Serial.print(ominute);
    Serial.print(":");
    Serial.println(osecond);
    rounds = 0;
  }
  
  drawClock(ohour,ominute,osecond);

  delay(10);
  
  chkSer();
}

void timeSync(void) {
  RtcDateTime dt = Rtc.GetDateTime();
  setTime(dt.Hour(),dt.Minute(),dt.Second(),dt.Day(),dt.Month(),dt.Year());
    
  Serial.print("Synced to: ");
  Serial.print(dt.Year());
  Serial.print("-");
  Serial.print(dt.Month());
  Serial.print("-");
  Serial.print(dt.Day());
  Serial.print("-");
  Serial.print(dt.Hour());
  Serial.print("-");
  Serial.print(dt.Minute());
  Serial.print("-");
  Serial.println(dt.Second());
}

void timeSave(void) {
  utc = now();
  
  RtcDateTime store = RtcDateTime(year(utc), month(utc), day(utc), hour(utc), minute(utc), second(utc));
  Rtc.SetDateTime(store);

  Serial.print("Synced to: ");
  Serial.print(year(utc));
  Serial.print("-");
  Serial.print(month(utc));
  Serial.print("-");
  Serial.print(day(utc));
  Serial.print("-");
  Serial.print(hour(utc));
  Serial.print("-");
  Serial.print(minute(utc));
  Serial.print("-");
  Serial.println(second(utc));
  
}

void setBrightness(byte brightness) {
  dimmer = brightness;
}

void chkSer(void) {
  unsigned int iy;
  byte im,id,iH,iM,iS;
  
  if(!Serial.available()) return;

  switch(Serial.read()) {
    case 'b':
      setBrightness(Serial.parseInt());
      Serial.print(F("Brightness changed to: "));
      Serial.println(dimmer);
      EEPROM.put(0, 0xAA);
      EEPROM.put(1, dimmer);
      break;
    case 't':
      iy = Serial.parseInt();
      im = Serial.parseInt();
      id = Serial.parseInt();
      iH = Serial.parseInt();
      iM = Serial.parseInt();
      iS = Serial.parseInt();
      setTime(iH,iM,iS,id,im,iy);
      Serial.println(F("System time changed"));
      break;
    case 'f':
      fader = false;
      EEPROM.put(0, 0xAA);
      EEPROM.put(3, 0);
      Serial.println(F("Fader off"));
      break;
    case 'F':
      fader = true;
      EEPROM.put(0, 0xAA);
      EEPROM.put(3, 1);
      Serial.println(F("Fader on"));
      break;
    case 'm':
      hmark = Serial.parseInt();
      EEPROM.put(0, 0xAA);
      EEPROM.put(2, hmark);
      Serial.println(F("HMark changed"));
      break;
    case 's':
      timeSync();
      Serial.println(F("Synced RTC to System"));
      break;
    case 'S':
      timeSave();
      Serial.println(F("Synced System to RTC"));
      break;
    default:
      Serial.println('?');
  }
}

Links: