Kategorien
Arduino

Arduino – MCP42010 mehrere digitale Potentiometer kaskadiert steuern

Arduino – MCP42010 – Beispiel Ansteuerung mehrerer digitaler Potentiometer

Nach dem Beispiel Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett und der grafischen Variante Node Red – Arduino – digitales Potentiometer MCP42010 steuern habe ich die Ansteuerung von 2 digitalen Potentiometern MCP42010 kaskadiert getestet.

Schaltung

 

Ansteuerung der beiden MCP42010

Die Ansteuerung des primären MCP42010 ist ausführlich in Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett beschrieben.
Schreiben in Potentiometer 1 -> B00010001 und in Potentiometer 2 -> B00010010
Als zweites Byte wird der Wert übertragen, den das ausgewählte Potentiometer annehmen soll.

Um den zweiten MCP42010 zu erreichen müssen 4 Bytes, statt bisher 2 gesendet werden. Beim dritten MCP42010 wären es dann 6, beim vierten 8 und so weiter.
Um ein Potentiometer des 2. MCP42010 direkt anzusteuern ohne die Inhalte des ersten Chips zu verändern, werden zwei weitere Bytes mit dem Wert 0 gesendet.
Siehe auch Bild links aus dem Datenblatt.

Schreiben in Potentiometer 3 -> B00010001 WERT B00000000 B00000000
Schreiben in Potentiometer 4 -> B00010010 WERT B00000000 B00000000

Das ganze ist von rechts nach links zu lesen.
Es werden 4 Bytes geschrieben oder besser hinein geschoben. Die ersten beiden Bytes (von links) werden von den folgenden beiden Bytes in den zweiten MCP42010 geschoben.
Im ersten MCP42010 kommen zwei mal Null an, also keine Änderungen an den Werten im 1. Chip.

Anbei ein Minimal Beispiel, wie in das Potentiometer 1 (Pot0) des zweiten MCP42010 der Wert 127 geladen wird.

Kategorien
Node Red

Arduino – Node Red – MCP42010 – Steuerung des digitalen Potentiometers

Arduino – Node Red – MCP42010 – Beispiel Steuerung des digitalen Potentiometers

Im Beitrag Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett habe ich dargestellt wie der MCP42010 über den seriellen Monitor der Arduino IDE gesteuert werden kann.
Jetzt will ich dieses etwas komfortabler zu tun.
Die Bedienung sollte aus dem Browser heraus erfolgen, optisch sehr ansprechend aussehen und auch mit dem Smartphone möglich sein.

Warum mit Node Red?

Node Red ist in der Standard Installation der Raspberry Pi enthalten, kostenlos und intuitiv bedienbar.
Durch die Möglichkeit den Programm Flow per drag and drop zusammen zu stellen, kommt man sehr schnell zu einem guten Ergebnis.
Für Prototypen und auch IOT Anwendungen eine echt tolle Sache.
Wo Licht ist, ist auch Schatten: Es verbraucht recht viel Ressourcen.
Dennoch kommt die Raspberry Pi 2 spielend damit zurecht und die Pi 3 logischerweise noch viel besser.

benötigte Funktionen des Flows

Der Flow soll die Eingaben, die ich im Experiment Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett per Hand gemacht habe übernehmen.
Der Flow soll die Rückgabe – Werte in einem Gauge Chart darstellen.

Eingabe:
1:Wert von 0-255 -> setzt Potentiometer1 auf den Wert und gibt die Spannung an A0 zurück
2:Wert von 0-255 -> setzt Potentiometer2 auf den Wert und gibt die Spannung an A1 zurück

Der Flow

  • einfach den folgenden Flow kopieren und unter Menü (rechts oben) -> Import – Clipboard einfügen
[{"id":"ebf0e947.110038","type":"ui_slider","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Slider","topic":"","group":"Pot1","order":1,"min":0,"max":"255","x":225.5,"y":125,"wires":[["25bd2695.9acaf2"]]},{"id":"b755b484.2bd75","type":"ui_text","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Wert","group":"Pot1","order":1,"format":"{{msg.payload}}","x":636.5,"y":102,"wires":[]},{"id":"ed9f01b2.dfae38","type":"ui_gauge","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Spannung in V an A0","group":"Pot1","order":1,"format":"{{value}}","min":0,"max":"5","x":681.5,"y":322,"wires":[]},{"id":"25bd2695.9acaf2","type":"function","z":"8ec3bd3.cce4dc","name":"Value to Command","func":"var msg1 = { payload:\"1:\" + msg.payload +\"\\n\"};\nreturn [msg, msg1];","outputs":"2","noerr":0,"x":440.5,"y":125,"wires":[["b755b484.2bd75"],["134514.6c0042ed"]]},{"id":"134514.6c0042ed","type":"serial out","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"d535ccdc.123838","x":658.5,"y":148,"wires":[]},{"id":"13db30d1.da3c67","type":"serial in","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"43aa993f.185738","x":186.5,"y":345,"wires":[["f39416bc.0495"]]},{"id":"f39416bc.0495","type":"function","z":"8ec3bd3.cce4dc","name":"Response to value","func":"//find A0 or A1\nvar value;\nif (msg.payload.indexOf(\"A0\") != -1) {\n    value = msg.payload.split(\"A0: \");\n    value = value[1].replace(\" Volt\", \"\");\n    msg.payload = value;\n    return [msg, null];\n} else {\n    value = msg.payload.split(\"A1: \");\n    value = value[1].replace(\" Volt\", \"\");\n    msg.payload = value;\n    return [null , msg];\n}","outputs":"2","noerr":0,"x":431.5,"y":345,"wires":[["ed9f01b2.dfae38"],["ddbfff6.2bdb3"]]},{"id":"8a48ef7d.33ba9","type":"ui_slider","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Slider","topic":"","group":"Pot2","order":1,"min":0,"max":"255","x":224,"y":227,"wires":[["127d632d.c0419d"]]},{"id":"5a58be54.e6b8d8","type":"ui_text","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Wert","group":"Pot2","order":1,"format":"{{msg.payload}}","x":635,"y":204,"wires":[]},{"id":"127d632d.c0419d","type":"function","z":"8ec3bd3.cce4dc","name":"Value to Command","func":"var msg1 = { payload:\"2:\" + msg.payload +\"\\n\"};\nreturn [msg, msg1];","outputs":"2","noerr":0,"x":439,"y":227,"wires":[["5a58be54.e6b8d8"],["ee1b0407.9fbca"]]},{"id":"ee1b0407.9fbca","type":"serial out","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"43aa993f.185738","x":657,"y":250,"wires":[]},{"id":"ddbfff6.2bdb3","type":"ui_gauge","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Spannung in V an A1","group":"Pot2","order":1,"format":"{{value}}","min":0,"max":"5","x":681,"y":370,"wires":[]},{"id":"147200e2.b8e19f","type":"ui_tab","z":"","name":"Test MCP42010","icon":"dashboard","order":"1"},{"id":"d535ccdc.123838","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":false},{"id":"43aa993f.185738","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":false}]

Video Ansteuerung MCP42010 mit Node Red

Kategorien
Arduino

Arduino MCP42010 – Steuerung und Test des Digital Potentiometers

Arduino MCP42010 – auf einem Steckbrett austesten

Es gibt viele Anleitungen digitale Potentiometer mit einer Arduino anzusteuern.
Meine Suche im Internet nach dem MCP42010 in Verbindung mit Arduino war sehr vielversprechend, führte aber erst nach einigen Versuchen zum Erfolg.
Viele Seiten und Foreneinträge diskutieren das Thema, beschreiben aber keine funktionierende Lösung.

Die Idee ist die beiden digitalen 10 Kiloohm Potentiometer an den Enden zwischen 5 Volt und Masse zu schalten und die Mitte des Potis auf jeweils einen analogen Eingang zu legen.
Je nach dem was jetzt für ein Widerstand (angesteuert) wird, wird die Spannung an den analogen Eingängen steigen oder fallen. Und das lässt sich auswerten.

Ich beschreibe, wie ich vorgegangen bin.

Zum Einsatz kam ein Arduino Nano Nachbau, der schon für etwas über 3,50 Euro zu haben ist und ein digitales Potentiometer MCP42010 (Datenblatt), was ich für ca. 2 Euro bei www.reichelt.de bestellt habe. Ich habe den Aufbau auch mit einer Arduino Uno getestet mit den selben IO Pins. Erfolgreich :-)

Wie in der folgenden Fritzing Grafik und dem Eagle Schaltplan zu erkennen, habe ich folgendermaßen verdrahtet.
Pin Belegung MCP42010MCP42010:
Pin 1 -> D10 Arduino, Pin2 -> D13 Arduino, Pin3 -> D11 Arduino, Pin4 -> Masse, Pin5 -> Masse, Pin6 -> A1 -> Arduino, Pin7 -> +5V, Pin8 -> + 5V, Pin9 -> A0 Arduino, Pin10 -> Masse, Pin11 -> +5V, Pin12 -> 5V, Pin13 – frei, Pin14 -> 5V

Arduino: Außer den Anschlüssen unter MCP42010 nur noch 5 Volt und Masse, um die Arduino mit Strom zu versorgen.

Ansteuerung des MCP42010

Auszug Datenblatt MCP42010Wie im Datenblatt auf Seite 18 zu sehen, muss CS (PIN 10) für die Dauer der Übertragung auf Low gesetzt werden.
Für die Übertragung werden 2 Bytes gesendet.
Als erstes ein Steuerbyte, in dem die Operation (Schreiben) und der Pot (das gewünschte der beiden Potentiometer) angegeben wird.
Schreiben in Potentiometer 1 -> B00010001 und in Potentiometer 2 -> B00010010
Als zweites Byte wird der Wert übertragen, den das ausgewählte Potentiometer annehmen soll.
Anbei ein Minimal Beispiel, wie in das Potentiometer 1 (Pot0) der Wert 127, also ca. Mittelstellung geladen wird.

//minimal Example to set the Pot0 of a MCP42010 to the value 127 
#include 
void setup() {
  // take the CS pin low to select the chip:
  digitalWrite(10,LOW);
  //  send in the address and value via SPI:
  SPI.transfer(B00010001);
  // write out the value 127
  SPI.transfer(127);
  // take the CS pin high to de-select the chip:
  digitalWrite(10,HIGH);
}
 
void loop() {
 
}

Das Programm zur ‘komfortablen’ Ansteuerung der 2 Potentiometer des MCP42010

Die Bedienung ist sehr einfach gehalten, wie auch schon im Video oben zu sehen war. Ich übergebe Werte an das digitale Potentiometer und werte die resultierende Spannung an den analogen Eingängen A0 und A1 aus.
Für die Dateneingabe und -Ausgabe nutze ich den Seriellen Monitor der Arduino IDE.

Eingabe:
1:Wert von 0-255 -> setzt Potentiometer1 auf den Wert und gibt die Spannung an A0 zurück
2:Wert von 0-255 -> setzt Potentiometer2 auf den Wert und gibt die Spannung an A1 zurück
s -> gibt Werte beide Potentiometer und die Spannungen an A0 und A1 zurück

// inslude the SPI library:
#include 
 
// set pin 10 as the slave select for the digital pot:
const int slave_Select_Pin  = 10;
const int analogInPin0      = A0; 
const int analogInPin1      = A1; 
String    inputString       = "";         // a string to hold incoming data
boolean   stringComplete    = false;      // whether the string is complete
int       level1            = 0;
int       level2            = 0;
 
void setup() {
     inputString.reserve(100);
     // set the slaveSelectPin as an output:
     pinMode (slave_Select_Pin, OUTPUT);
     Serial.begin(9600);
 
     // initialize SPI:
     SPI.begin();
     MSP42010PotWrite(slave_Select_Pin, B00010001, level1);
     MSP42010PotWrite(slave_Select_Pin, B00010010, level2);
}
 
void loop() {
  if (stringComplete) {
    //check ob R1:
    if (inputString.substring(0, 2) == "1:") {
      level1 = inputString.substring(2).toInt();
      MSP42010PotWrite(slave_Select_Pin, B00010001, level1);     
      printValues(level1, analogInPin0);
    }
    //check ob R2:
    if (inputString.substring(0, 2) == "2:") {
      level2 = inputString.substring(2).toInt();
      MSP42010PotWrite(slave_Select_Pin, B00010010, level2); //Datasheet Page 18
      printValues(level2, analogInPin1);
    }
    //check ob s
    if (inputString.substring(0, 1) == "s") {
      printValues(level1, analogInPin0);
      printValues(level2, analogInPin1);
    }
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}
 
void MSP42010PotWrite(int slaveSelectPin, byte address, int value) {
     // take the SS pin low to select the chip:
     digitalWrite(slaveSelectPin,LOW);
     //  send in the address and value via SPI:
     SPI.transfer(address);
     SPI.transfer(value);
     // take the SS pin high to de-select the chip:
     digitalWrite(slaveSelectPin,HIGH);
}
void printValues(int level, int aPin) {
      delay(5);
      int pot = 0;
      if (aPin == 15) {
        pot = 1;
      }
      Serial.print("level Pot");
      Serial.print(pot);
      Serial.print(": ");
      Serial.print(level);
      Serial.print(" Spannung an A");
      Serial.print(pot);
      Serial.print(": ");
      double sl = analogRead(aPin);
      sl = sl * 5 / 1024; 
      Serial.print(sl);
      Serial.println(" Volt");  
}
/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    } else {
      inputString += inChar;
    }
  }
}

Papst ebm G1G133-DE19-15* Lüfter Drehzahl Messen / Steuern mit Arduino und Raspberry Pi

Auf Ebay werden ab 13 Euro gebrauchte Lüfter mit Gleichstrommotoren angeboten, welche mit bis zu Luftstrom: 225 m³/h bei maximal 45 Watt sehr gute Leistungswerte aufweisen.
Für mich war wichtig, dass ich die Drehzahl des Lüfters geregelt bekomme, da ich nicht immer volle Leistung benötige.

In den Bewertungen des Produkts unten in der Auktion, wurde angekündigt, dass sich die Drehzahl des Motors über PWM steuern lässt.
Auch dieses Datenblatt eines fast baugleichen Lüfters lässt auf Seite 4 die Vermutung zu, dass sich die Drehzahl über ein PWM Signal steuern lässt. Das hat in meinem Falle nicht funktioniert.

Nach vielen Versuchen ein PWM Signal anzulegen und einen Drehzahlimpuls abzuholen, habe ich mich dazu entschlossen den Lüfter auseinander zu nehmen.

Im Inneren ist kein normaler Gleichstrommotor, dass ist mehr ein Mikrocontroller – gesteuertes High-Tech Produkt. Ich bin mir sicher, dass die Beschaltung eine Drehzahlsteuerung zulassen würde und wenn dafür der Code des Mikrocontrollers etwas angepasst werden müsste.

Weiter gehts auf den folgenden Seiten:

Kategorien
ATMega8

ATMega8 – Registerinhalte auf dem Mikrocontroller über serielle Schnittstelle steuern

Pollin_Board_klein
Wie im Beispiel Hello World über serielle Schnittstelle senden und im Beispiel LED’s des Pollin Evaluationboards über die serielle Schnittstelle steuern dargestellt, ist es recht einfach möglich Buchstaben oder Bytes zu einem PC zu übertragen und auch anders herum vom PC aus Schaltzustände zu verändern.
Die neue Herausforderung ist es nun Registerinhalte via serieller Schnittstelle zu füllen und Diese wieder auszulesen.

Gedacht ist die Übung als Vorbereitung für eine interne Systemuhr auf dem ATMega8, die von einem PC oder z.B. auch der Raspberry Pi gestellt und abgelesen werden kann.

PollinBoard_ATMega8_Registerinhalte_per_UART_steuern_und_ausgeben_Ablaufplan_VSWie im Ablaufplan (Bild links) dargestellt, habe ich das Programm so strukturiert, dass

  • im Hauptprogramm die Variablen initialisiert werden und der Interrupt sobald ein Byte über RX/UART empfangen wird, aktiviert ist
  • Das Unterprogramm IncommingByte entscheidet, ob es sich um ein Aktives, oder Neues Unterprogramm handelt und ruft ein weiteres Unterprogramm FunctionCall auf, was an das aktive oder gewählte Unterprogramm weiterleitet.
  • Das Unterprogramm StelleUhr, wird durch das Senden eines Bytes mit dem Inhalt 1 aufgerufen und erwartet das danach 3 weitere Bytes als Inhalt für die Register Stunde, Minute und Sekunde via RX/UART übergeben werden. Diese werden in den Registern gespeichert.
  • Das Unterprogramm Sende Uhrzeit, wird mit einem Byte mit Inhalt 2 aufgerufen und sendet 3 Byte mit den Inhalten Stunde, Minute und Sekunde zurück an den PC.

Der hier abgebildete Assemblercode ist mit vielen Kommentaren versehen.

Quellcode des Assemblerprogramms:

; avrdude -p m8 -c stk500v2 -P /dev/ttyACM0 -U flash:w:Registerinhalte_via_UART_steuern_und_ausgeben.hex
; 13.9.2013 Das Programm soll Registerinhalte per serielle Datenübertragung manipulieren können und diese auch wieder ausgeben
.NOLIST
;.INCLUDE "/home/henry/Dokumente/Mikrocontroller/AVR-Assembler/AVR_Definitionsfiles/m8def.inc"
.INCLUDE "m8def.inc"
.LIST
;
.def Sekunde                = R2
.def Minute                 = R3
.def Stunde                 = R4
;--------------------------------
.def temp                   = R16               ; Register 16 der Variable temp zuweisen 
.def ByteNummer             = R17               ; Enthält die Nummer des aktuell übertragenen Bytes innerhalb eine Unterprogramms
.def aktivesUnterprogramm   = R19               ; Enthält die numerische ID des aktuell aktiven Unterprogamms
.def EmpfRXByte             = R20               ; Enthält das zuletzt via. UART empfangene Byte 
 
.equ F_CPU = 16000000                           ; Systemtakt in Hz
.equ BAUD  = 9600                               ; Baudrate
 
; Berechnungen
.equ UBRR_VAL   = ((F_CPU+BAUD*8)/(BAUD*16)-1)  ; clever runden
.equ BAUD_REAL  = (F_CPU/(16*(UBRR_VAL+1)))     ; Reale Baudrate
.equ BAUD_ERROR = ((BAUD_REAL*1000)/BAUD-1000)  ; Fehler in Promille
 
.if ((BAUD_ERROR>10) || (BAUD_ERROR<-10))       ; max. +/-10 Promille Fehler
  .error "Systematischer Fehler der Baudrate grösser 1 Prozent und damit zu hoch!"
.endif
 
; Startvektoren 
.org 0x00
    rjmp main
.org URXCaddr                                   ; Interruptvektor für UART-Empfang
    rjmp IncommingByte
 
; --------------------------------Hauptprogramm--------------------------------------
main:
 
    ; Stackpointer initialisieren
    ldi     temp, HIGH(RAMEND)
    out     SPH, temp
    ldi     temp, LOW(RAMEND)
    out     SPL, temp
 
    ; Baudrate einstellen
    ldi     temp, HIGH(UBRR_VAL)
    out     UBRRH, temp
    ldi     temp, LOW(UBRR_VAL)
    out     UBRRL, temp
 
    ; Frame-Format: 8 Bit
    ldi     temp, (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)     out     UCSRC, temp     sbi     UCSRB, RXCIE                        ; Interrupt bei Empfang     sbi     UCSRB, RXEN                         ; RX (Empfang) aktivieren          sei                                         ; Interrupts global aktivieren loop:     rjmp    loop                                ; Endlosschleife / idle mode ; ---------------------------ENDE Hauptprogramm-------------------------------------- ; ---------------------------IncommingByte------------------------------------------- ; Interruptroutine: wird ausgeführt sobald ein Byte über das UART empfangen wurde IncommingByte:     in      EmpfRXByte, UDR                     ; empfangenes Byte lesen,                                                 ; dadurch wird auch der Interrupt gelöscht     cpi     aktivesUnterprogramm, 1             ; vergleich aktivesUnterprogramm mit 1     brge    UPAufruf                            ; ist aktivesUnterprogramm > 0, springe zu UPAufruf
    mov     aktivesUnterprogramm, EmpfRXByte    ; kopiere EmpfRXByte in aktivesUnterprogramm
    clr     ByteNummer                          ; setze ByteNummer aud 0
 
UPAufruf:
    rcall   FunctionCall                        ; rufe Unterprogramm FunctionCall auf
EndIncommingByte:
    reti                                        ; Interrupt beenden
; ----------------------Ende-IncommingByte-------------------------------------------
 
; ---------------------------FunctionCall--------------------------------------------
; Abfrage aktivesUnterprogramm und Aufruf der entsprechenden Unterprogramme
FunctionCall:
    cpi     aktivesUnterprogramm, 1
    breq    Byte1                               ; Wenn eine 1 übertragen wurde zu Byte1 springen 
    cpi     aktivesUnterprogramm, 2
    breq    Byte2                               ; Wenn eine 2 übertragen wurde zu Byte2 springen 
    rjmp    EndFunctionCall                     ; zum Unterprogramm - Ende (Es wurde kein Wert der einem gültigem Unterprogarmm entspricht übertragen.)
 
Byte1:
    rcall   StelleUhr                           ; StelleUhr aufrufen
    rjmp    EndFunctionCall                     ; zum Unterprogramm - Ende
Byte2:
    rcall   SendeUhrzeit                        ; SendeUhrzeit aufrufen
    rjmp    EndFunctionCall                     ; zum Unterprogramm - Ende
EndFunctionCall:
    ret                                         ; Ende - zurück springen
; ----------------------Ende-FunctionCall--------------------------------------------
 
; ---------------------------StelleUhr-----------------------------------------------
StelleUhr:
    cpi     ByteNummer, 1                       ; vergleich ByteNummer mit 1
    breq    StelleSekunde                       ; ist ByteNummer = 1, springe zu StelleSekunde
 
    cpi     ByteNummer, 2                       ; vergleich ByteNummer mit 2
    breq    StelleMinute                        ; ist ByteNummer = 2, springe zu StelleMinute
 
    cpi     ByteNummer, 3                       ; vergleich ByteNummer mit 3
    breq    StelleStunde                        ; ist ByteNummer = 3, springe zu StelleStunde
 
    rjmp    ErhoeheByteNummer                   ; springe zu ErhoeheByteNummer
 
StelleSekunde:
    mov     Sekunde, EmpfRXByte                 ; Kopiere EmpfRXByte in Sekunde
    rjmp    ErhoeheByteNummer                   ; spinge zu ErhoeheByteNummer
 
StelleMinute:
    mov     Minute, EmpfRXByte                  ; Kopiere EmpfRXByte in Minute
    rjmp    ErhoeheByteNummer                   ; spinge zu ErhoeheByteNummer
 
StelleStunde:
    mov     Stunde, EmpfRXByte                  ; Kopiere EmpfRXByte in Stunde
    clr     aktivesUnterprogramm                ; setze aktivesUnterprogramm auf Null, wir sind fertig mit Uhr stellen :-)
    rjmp    EndStelleUhr                        ; spinge zu EndStelleUhr
 
ErhoeheByteNummer:
    inc     ByteNummer                          ; erhöhe ByteNummer um 1
EndStelleUhr:
    ret                                         ; Ende - zurück springen
; ----------------------Ende-StelleUhr-----------------------------------------------
 
; ---------------------------SendeUhrzeit--------------------------------------------
SendeUhrzeit:
    cbi     UCSRB, RXEN                         ; RX (Empfang) deaktivieren
    sbi     UCSRB, TXEN                         ; TX (Senden) aktivieren
 
Sekunde_wait:
    sbis    UCSRA,UDRE                          ; Warten bis UDR für das nächste Byte bereit ist
    rjmp    Sekunde_wait                        ; Springe zurück zu Sekunde_wait, solange UDR noch nicht bereit ist
    out     UDR, Sekunde                        ; sende das Byte Sekunde via UART
 
Minute_wait:
    sbis    UCSRA,UDRE                          ; Warten bis UDR für das nächste Byte bereit ist
    rjmp    Minute_wait                         ; Springe zurück zu Minute_wait, solange UDR noch nicht bereit ist
    out     UDR, Minute                         ; sende das Byte Minute via UART
 
Stunde_wait:
    sbis    UCSRA,UDRE                          ; Warten bis UDR für das nächste Byte bereit ist
    rjmp    Stunde_wait                         ; Springe zurück zu Stunde_wait, solange UDR noch nicht bereit ist
    out     UDR, Stunde                         ; sebnde das Byte Stunde via UART
 
    cbi     UCSRB, TXEN                         ; TX (Senden) deaktivieren
    sbi     UCSRB, RXEN                         ; RX (Empfang) aktivieren
    clr     aktivesUnterprogramm                ; setze aktivesUnterprogramm auf Null, wir sind fertig mit Uhrzeit ausgeben :-)
EndSendeUhrzeit:
    ret                                         ; Ende - zurück springen
; ----------------------Ende-SendeUhrzeit--------------------------------------------

 

Video, zur Demonstration

 

Wooden Generator 1 – Experiment 1



Da nicht wie ursprünglich geplant nur eine positive Halbwelle erzeugt wird, sondern ein richtiger Wechselstrom wie unter Wooden Generator 1 bereits beschrieben, reagiere ich auf die für mich simpelste Weise darauf.
LED’s verbrauchen wenig Strom. Es kommt ja auch (noch) relativ wenig :-)
Also die positive Halbwelle bringt eine LED zum leuchten und die Negative eine entgegengesetzt Gepolte.

Schaltplan Experiment 1 Versuchsaufbau Experiment 1

Das folgende Video gibt einen Eindruck wie lang und wie stark die LED’s leuchten.

Kreissägeblatt – Generator – Experiment 1

Das erste Experiment mit dem Stator auf dem Kreissägeblatt sollte:

  • einen Anhaltspunkt geben, wie hoch die Induzierte Spannung ist,
  • mit welcher Leistung ich rechnen kann
  • ob das mit den drei Phasen so funktioniert, wie ich es mir vorgestellt habe.
Vorschau_Spulen_Experiment1_1
Vorschau_Spulen_Experiment1_2
Vorschau_Gleichrichtung_Stern_3Phasen


Der Aufbau sollte möglichst einfach sein und sich schnell realisieren lassen, weshalb ich mich dafür entschied 3 Spulen mit je 50m 0,25 mm² Kupferlackdraht zu wickeln.
50 Meter waren gerade verfügbar. Es sind genau 400 Windungen pro Spule heraus gekommen.
Diese wurden ‘im Verhältnis 4:3’ zu den 28 Magneten, also mit 17,14 Grad Abstand ausgehend von der Stator-Mitte auf ein Stück Sperrholz mittels handelsüblichen Bastel-Leim aufgeklebt.
Die Drahtenden wurden in Sternschaltung verbunden, so dass 3 Anschlussdrähte von der Spulenseite her vorhanden sind.
Dann habe ich mit 6 Si-Dioden einen Gleichrichter, genau wie er in Autolichtmaschinen eingesetzt wird, aufgebaut.

Der erste Test lief sehr erfolgversprechend. Der Stator, also das Kreissägeblatt lag auf einer Drehscheibe, so dass ich es leicht per Hand in Rotation versetzen konnte.
Die Spulen wurden während des Laufes so genau es eben ging über die Magneten gehalten.

Ein paar der Versuche habe ich mit der Video Kamera festgehalten, um ermitteln zu können, welche Leistung, bei welcher Drehzahl abgegeben wird, um eine Vorstellung zu bekommen, was aktuell an Leistung raus kommt und in welche Richtung weitere Versuche abgewandelt werden sollten.

Wie in den Grafiken zu erkennen, wurde eine stolze Leistung von ca. 1,6 Watt bei 190 U/min erzeugt, was eine enorme Steigerung zu allen Vorgänger Versuchen ist.

 

Eigenbau Scheibengenerator auf Kreissägeblatt für niedrige Drehzahlen

Nachdem ich nun schon ein Windrad aufs Dach gebaut habe, muss jetzt noch der geeignete Generator ran. Der Versuch einen Permanentmagnet-Elektromotor als Generator zu verwenden und diesen mittels Rundriemen am Windrad anzubinden ist erwartungsgemäß der volle Reinfall gewesen.

Tipp: Nichts einreden lassen! – Riemen, Getriebe oder sonstige Übersetzungen verderben das gesamte Windradprojekt. Ohne Last läuft das Windrad bei unter 2m/s an. Allein den Motor (Generator) in Drehung zu versetzen brauchte 5m/s Wind. Das reichte aber auch nicht. Ladespannung für die Autobatterie kam erst bei richtig fett Wind, wie es im Monat vielleicht 20 Stunden vorkommt. Die Ladeleistung lag dann bei ca. 5 Watt. -> Abhaken!

Back to the roots;

Scheibengenerator - Saegeblatt_mit_MagnetenEin Scheibengenerator ist für geringe Drehzahlen geeignet. Je größer der Durchmesser ist, desto höher ist die Winkelgeschwindigkeit. Das ist von Vorteil, da ab 60 U/min mindestens 1 Watt kommen soll.

Es gibt ja diverse Beispiele im Netz, die Eigenbauprojekte von Scheibengeneratoren zeigen. Die meisten sehen recht massiv aus, basieren auf Bremsscheiben für den Stator und sind für höhere Drehzahlen (500/min und höher) ausgelegt. Es lässt sich aber viel lernen.

Scheibengenerator - Saegeblatt_mit_Magneten_und_SpulenIch will es diesmal gleich richtig machen und plane einen 3-Phasen Generator. Das Verhältnis Magneten zu Spulen beträgt 4:3. Die Webseite beschreibt es recht schön. Des weiteren sind die Spulen so aufzubauen, dass die Magneten in die Mitte passen, ohne von Leitern überdeckt zu werden.

Ich habe mich für ein Kreissägeblatt mit 41,5cm Durchmesser entschieden. Zudem habe ich mir bei Ebay 30 Magneten mit einem Durchmesser von 28,8mm und 3,3mm Stärke gekauft. Haftkraft 28KG/Magnet! Ich hätte gern stärkere (dickere) Magneten genommen, bin aber ehrlich gesagt zu geizig gewesen 5€ oder mehr pro Magnet auszugeben. -> Ich benötige genau 28 davon, die in einem Radius von 185mm vom Kreismittelpunkt zum Magnetmittelpunkt im Abstand von ca. 12,86 Grad angebracht werden.

Die Spulen werden im Winkel von 17,14 Grad angeordnet, so dass das Verhältnis von 4:3 eingehalten wird. Für die ersten Versuche werde ich eine Spule je Phase verwenden.

Der Aufbau:

Scheibengenerator - Vorschau_Schablone_Magneten_Kreissaegeblatt1Scheibengenerator - Vorschau_Schablone_Magneten_Kreissaegeblatt2
Scheibengenerator - Vorschau_Schablone_Magneten_Kreissaegeblatt3Scheibengenerator - Vorschau_Schablone_Magneten_Kreissaegeblatt4
Scheibengenerator - Vorschau_Schablone_Magneten_Kreissaegeblatt5Scheibengenerator - Free-Cad_Konstruktionszeichnung
Scheibengenerator - svg_grafik

Um die Magneten an der richtigen Stelle aufkleben zu können, habe ich mir eine Schablone aus Sperrholz ausgesägt.
Es war mir zu riskant die Position nur auf dem Blatt zu markieren und zu hoffen, dass die Magneten sich genau positionieren lassen, ohne sich anzuziehen.
Schließlich schwimmen die Teile ein wenig auf dem Kleber.
Ich habe UHU Endfest 300 genommen. Das sollte halten.

Die Zeichnung für die Bohrlöcher der Schablone, habe ich mit free-cad erstellt.
Das ganze wurde dann in Inkscape als SVG-Grafik übertragen ausgedruckt und aufgeklebt.
Aussägen, fertig!

Da der Stator sich auch drehen muss, habe ich kurzerhand eine drehbare Unterlage für einen Fernseher oder ähnliches mittig unter gelegt. Für Versuchszwecke funktioniert das recht gut. Hier ist es im Video zu sehen.

Wer auf das Free-Cad Logo klickt, kann sich sofern er Free-Cad installiert hat meine Konstruktionszeichnung runter laden, genau so wie die Zeichnung zur Bohrschablone sich hinter dem SVG Logo verbirgt. Als Editor für die SVG Grafiken eignet sich am besten Inkscape.

 

Eigenbau Wooden Generator 1

Recht schnell wurde quick an dirty eine Versuchsanordnung aufgebaut. Ich habe Wert darauf gelegt möglichst viel Masse nach außen zu verlagern, damit das Drehmoment höher wird und einmal Anschieben ein Stück vorhält. Anbei ein paar Bilder vom Aufbau.

Bauplan:

Ich habe keine Neodym-, sondern ganz normale Keramikmagneten verwendet. Die haben zwar nur ca. 20 Prozent der Leistung eines Neodymmagneten mit gleichem Ausmass, sind aber wesentlich günstiger.
Auf einem Durchmesser von 14,7 cm (Magnetmitte), habe ich 10 Magnete Durchmesser 30mm Höhe 5mm für ca. 3 Euro aus dem Opitec Katalog angebracht.

Bei 60 U*min-1 ergibt das eine stolze Geschwindigkeit von 0,46 m/s im Magnetmittelpunkt. Pro Sekunde würden dann 10 Magneten die Spule(en) überqueren.

Da der ‘Generator’ von der Spannung her sowieso nicht die Welt bringen würde und jede Diode, die im Stromkreis verbaut ist (SI) erstmal 0,7 Volt für sich benötigt, habe ich die Magneten alle mit dem Nordpol nach oben angebracht. Wenn ein Leiter über quer zu den magnetischen Feldlinien bewegt wird, sollte dann Strom in nur eine Richtung fliessen. Soweit zur Theorie. Wie man im folgenden Bild sehen kann, wird doch eine Wechselspannung erzeugt. Lange Zeit war mir unklar warum. Das liegt zum großen Teil auch daran, dass losgeschraubt wird ohne die Grundlagen mal gewissenhaft zu lesen.

Wenn ich eine Spule so wie hier vorgesehen über einen Magneten bewege, wird solange sich nur eine Hälfte der Spule über dem Magnet befindet ein Stromfluss einstellen. Sobald die zweite Spulenseite den Magneten überstreift, kommt ein entgegengerichteter Stromfluß hinzu, was bedeutet, dass beide Ströme sich unter Umständen aufheben. Tolle Konstruktion! Denken hätte geholfen. Es läßt sich an dem Punkt bereits erkennen, dass Potential zur Verbesserung da ist. Ich wurde trotzdem mit dem Leuchten 2er Leuchtdioden belohnt. Ganz erfolglos war es also nicht.

Für den ersten Test habe ich eine (einzige) Spule verwendet. Leider hat diese noch einen 8mm Eisenkern, aber ohne gab es auf die Schelle keine Erfolge. Ich habe einen alten Spulenkörper genommen und 50 Meter 0,25 mm² Kupferlackdraht zu ca. 950 Windungen gewickelt. Das reichte dann bei schnellen anschieben einige Sekunden 2 kleine Leuchtdioden (1,7V – 5mA) aufleuchten zu lassen. Das es funktioniert ist damit schonmal nachgewiesen, auch wenn die Ausbeute miserabel war.

Kategorien
Messen - Steuern - Regeln

Drehzahlmessung und Datenerfassung durch Videobeweis

Die Idee entstand beim Versuch zu ermitteln, was aus meinem Kreissägeblatt Scheibengenerator für eine Leistung kommen könnte.

Das Sägeblatt, also der Stator mit den Neodym – Magneten liegt auf einem Drehteller, der eigentlich unter einen Fernseher oder ähnliches gehört und wird per Hand angeschoben. Ein typischer Versuchsaufbau im Heimbereich eben.

Die Spulen für die Stromerzeugung, werden auch per Hand in die Richtung der Magneten geführt, was dafür sorgt, keine Hand mehr frei zu haben.

Ich kann nun punktgenau ablesen wie viel Spannung über einem Verbraucher (kleine Lämpchen) anliegt und wie viel Strom fließt. Daraus ist es einfach auf die abgegebene Leistung zu schließen.
Leider aber nur Pi mal Daumen.
Aussagen wie: Wenn ich schnell drehe, dann Leistung 1, wenn langsam, dann Leistung 2, sind möglich. Unbefriedigend.

Selbst wenn ich nun einen Drehzahlmesser zusätzlich ins Spiel bringe, wird es nicht einfach den Stator anzuschieben, die Spulen zu halten, die Werte punktgenau zur selben Zeit abzulesen.

Die Idee:

  • Sägeblatt an einer Stelle markieren, um eine Umdrehung gut nachvollziehen zu können.
  • Die Versuchsanordnung so aufbauen, dass eine Videokamera das Sägeblatt und die Messgeräte aufnehmen kann.

Das Video zur Idee:

Bemerkungen:

  • geeignet für Drehzahlen unter 300 U/min, da eine normale Videokamera nur 25 Bilder pro Sekunde aufnimmt.
  • Außer der Videokamera, werden nur noch 2 Vielzweckmessgeräte benötigt, die meist bereits vorhanden sind.
  • Das Ergebnis ist verblüffend. Ich kann damit direkt vergleichen, ob eine Änderung im Aufbau sich so auswirkt, wie ich es gern hätte.
  • Die Auswertung ist jederzeit wiederholbar. Habe ich erst mal das Video, kann ich es auch später auswerten.