Posts mit dem Label ATtiny werden angezeigt. Alle Posts anzeigen
Posts mit dem Label ATtiny werden angezeigt. Alle Posts anzeigen

Samstag, 31. Juli 2021

Mini Solar Projekt mit ATtiny25/45/85


Gerade baue ich einen RC Crawler und hin und wieder kommen mir Ideen, was man da noch umsetzen könnte. Die meisten Ideen verwerfe ich, nur wenige verbleiben bei mir als Notiz in OneNote.
Zum Schluss gibt es dann doch meistens zu viele Gründe, warum ich eine Idee nicht mehr weiter verfolge. Das fängt häufig damit an, das ich nicht die passenden Teile habe oder ich will die fehlenden Komponenten nicht bestellen.

Heute konzentrierte ich mich auf die Teile, die ich da habe. In meinem Sortierschrank befinden sich zahlreiche Komponenten mit denen sich etwas anfangen lässt. Allerdings meine ich, wenn ich von Basteln spreche, eher etwas auszuprobieren oder sich damit auseinandersetzen und dann ein Beispiel darüber zu schreiben. Diesmal soll es ein fertiges Teil sein, dass einfach zu modden ist.


Benötigt wird:

  • Solar Platte 40mm x 40mm, 2V, 40mA
  • 5 LEDs (Idealerweise Rot, wegen der Erforderlichen Spannung)
  • ATtiny 45 oder 85
  • 5 x 10 Ohm Widerstände

Zielbeschreibung

Mit der Solar Zelle soll ein ATtiny 45/85 betrieben werden, dass mit 1MHz läuft. Die 5 LEDs sollen einen Dezimal Wert in Binär abbilden, der hier einfach hochgezählt wird bis 32. Wenn die 32 erreicht wurde, sollen alle LEDs nacheinander ausgeschaltet werden, anschließen hinter einander wieder an und dann wieder hintereinander aus.


Schaltung

Kommen wir zur Schaltung, die eigentlich für keine stabile Spannung ausgelegt sein kann. Die Solarplatte, die ich hier verwendet, erzeugt bei Sonnenlicht etwas mehr als 2V und 40mA. Genug um den ATtiny mit 1,8V Mindestspannung und mit 1MHz zu betreiben. Die Stromaufnahme von 300µA ist so klein, dass sie zu anderen betreibbaren Komponenten kaum auffällt. Da können glatt noch zwei LEDs mehr mit betrieben werden (naja, nicht glatt 20mA) oder 19 x Low Current LEDs. Die Low Current LEDs wollte ich als erstes verwenden, jedoch ist das Licht zu schwach bei Sonnenlicht zu sehen. Die normalen LEDs leuchten nicht mit ihrer Nennleistung, aber sie sind dennoch deutlich heller.

Nun hatte ich zu den benötigten Teilen 5 LEDs genannt und in der Anforderung sollten sogar alle 5 zum Leuchten gebracht werden. Nun direkt werden nicht alle an sein. Durch die Programmierung werden die LEDs im Schnell-Wechsel durchgeschaltet, so das für uns alle LEDs scheinbar an sind. Vielleicht kann man das leichte Flimmern (Ähnlich wie bei PWM Betrieb) sehen, aber dafür leuchten mehr, als eigentlich die Solar Platte an Strom her geben kann.



Alle Lampen mit geringen Stromverbrauch

Der Wechsel wird durch eine Methode verwaltet, die die einzuschaltenden Ausgänge steuert.

 void LightControllerShow() {  
  if(mCurrentLED < 4)   
   mCurrentLED++;   
  else  
   mCurrentLED = 0;  
  for(int i = 0; i < 5; i++) {  
   if(mCurrentLED == i && mLightsOn[i] == true)  
    digitalWrite(i, HIGH);  
   else  
    digitalWrite(i, LOW);  
  }  
 }  

Das Beispiel weist mehr Aufwand auf, als bei einem üblichen Programmablauf, bei dem die Ausgänge alle wirklich durchgeschaltet sind. Dafür wird nur noch ein Fünftel des Stroms benötigt.

 

Testlauf

Auch wenn später der ATtiny mit nur 1 MHz läuft, können wir dies testweise mit einem Arduino prüfen. Die Kamera ist mit einer schnellen Verschlusszeit eingestellt, deshalb wird der Schaltvorgang als Flimmern war genommen im folgendem Clip.

 

 

Zielgerade

Kommen wir zu dem eigentliche Programm. Wie bereits in der Anforderungen beschrieben, soll bis 32 gezählt werden. Der Wert wird wiederum Binär auf die 5 LEDs ausgegeben. Kommen wir zum nächsten Codeabschnitt.

 bool mLightsOn[5];  
 int mLastTime = 0, mCurrentLED = 0, mVal = 0;  
 void setup() { for(int i = 0; i < 5; i++) { pinMode(i, OUTPUT); mLightsOn[i] = false; } }  
 void loop() {  
  LightControllerShow();  
  int currentTime = millis();  
  if(currentTime - mLastTime > 1000) { mLastTime = currentTime; Next(); }  
 }  
 void Next() {  
  if(mVal > 32) { mVal = 0; RunLight(); } else { mVal++; }  
  DecimalToBinar(mVal);  
 }  
 void DecimalToBinar(int val) {  
  int bin = 16, index = 0;  
  SetOnTo(-1);  
  while(true) {  
   if(val >= bin) { mLightsOn[index] = true; val -= bin; }  
   else { mLightsOn[index] = false; }  
   index++; bin /= 2;  
   if(val <= 0 || index > 4 || bin == 0) { break; }  
  }  
 }  
 void RunLight() {  
  int iteration = 0,lastTime = 0, lightOn = 0;  
  bool up = true;  
  SetOnTo(lightOn);  
  while(true) {   
   if(iteration > 10) { break; }  
   LightControllerShow();  
   int currentTime = millis();  
   if(currentTime - lastTime > 200) {  
    lastTime = currentTime;  
    if(up) { lightOn++; } else { lightOn--; }  
    if(lightOn >= 5) { up = false; lightOn = 4; }  
    if(lightOn < 0) { up = true; lightOn = 0; iteration++; }  
    SetOnTo(lightOn);  
   }  
  }  
 }  
 void SetOnTo(int indexLight){  
  for(int i = 0; i < 5; i++) { mLightsOn[i] = false; }  
  if(indexLight < 0) { return; }  
  mLightsOn[indexLight] = true;  
 }  
 void LightControllerShow() {  
  if(mCurrentLED < 4) { mCurrentLED++; }  
  else { mCurrentLED = 0; }  
  for(int i = 0; i < 5; i++) {  
   if(mCurrentLED == i && mLightsOn[i] == true) { digitalWrite(i, HIGH); }  
   else { digitalWrite(i, LOW); }  
  }  
 }  


Ab auf den ATtiny

Der ATtiny 45 erfüllt die Anforderung. Ob nun ein ATTiny25 geht, konnte ich wegen fehlendem Bestand nicht prüfen.

Nun sollte der Arduino IDE im Board Manager die Unterstützung für ATtiny haben. Falls nicht, dann solltet ihr in: File -> Preference und dann in 'Additional Boards Manager URLs:' diesen Link eintragen:

https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json

 

Für mehr Detail zu ATtiny und Arduino kann ich diese Seite empfehlen: 

Programming an ATtiny with Arduino

 

Arduino UNO als ISP verwenden

Der Arduino kann einen ATtiny mit dem Ziel Code beschreiben. Dazu muss der Arduino mit dem Code für ISP beschrieben werden. Die sollte unter den Beispiel Programmcode hinterlegt sein.

Auswählen und dann auf den Arduino.

 

Ziel Einstellung

Board: ATtiny25/45/85

Processor: ATtiny45

Clock: Internal 1 MHz


Bevor der Code geladen wird, muss der Bootloader auf den ATtiny. Wie bereits im letzten Bild zu sehen, kann über den letzten Eintrag 'Burn Bootloader' der ATtiny gebracht werden.

Nun kann der Sketch auf den ATtiny geschrieben werden und anschließend in die Schaltung eingebracht werden.

 

Fertig

Nun brauchen wir etwas Sonnenlicht, um das Ergebnis zu prüfen. Je nach Sonnenschein kann auch indirekt die Solar Platte Energie erzeugen. Auf dem Hinterhof konnte selbst im Schatten genügend Energie erzeugt werden, dass die Schaltung anlief.


 

Was nun?

Statt auf dem Breadboard die Schaltung weiter laufen zu lassen, kann man daraus etwas geschlossenes bauen. In meinem Fall habe ich daraus ein Gepäckstück für mein RC Modell gebaut, so dass halt nicht nur das Aussehen einer So
larplatte erfüllt, sondern
auch etwas Funktion zeigt.

 

 

Source

Alles über die Sourcen zum Thema ATtiny25/45/85:  

Highlowtech - Programming an ATtiny with Arduino


Und Natürlich:

Github - MiniSolarProjectWithATtiny

Dienstag, 12. Mai 2015

Beleuchtung mit dem ATtiny 45 (Ausbessern)

Quadrocopter_10

In meinem vorigen Post habe ich bereits geschrieben, dass die vorhandenen LEDs für meine Beleuchtung nicht alle vollständig durchgesteuert werden können. Der Grund liegt an dem verwendeten Spannungsregler, der für den Betrieb ca. 100mA zur Verfügung stellt und kurzzeitig auch bis zu 150mA. Die Lichtausbeute war somit nur eingeschränkt möglich.

Quadrocopter_12

Neu ist eine hintere LED Leiste mit fünf blauen und vier weißen LEDs. Dieser benötigt alleine bereits bis zu 200mA und da würde schon der einfache Spannungsregler nicht lange funktionieren. Nun mit dem etwas größer dimensionierten Spannungsregler sind solche Schwierigkeiten obsolet und am Programm muss nichts extra verändert werden, um Einsparungen für den Stromverbrauch vorzunehmen. Zudem können alle 16 LED RGBs (WS2812b) vollständig durchgeschaltet werden, ohne das die Spannung einbricht.

Quadrocopter_08

Kommen wir zu den Änderungen. Wie bereits erwähnt verwende ich einen anderen Spannungsregler von STMicroelectronics. Die Bezeichnung lautet L7805CV und fällt schon durch ein größeres Gehäuse auf, das der TO-220 Norm entspricht. Mit dem neuen kommen auch ungepolte Kondensatoren mit einer deutlichen kleineren Kapazität.

image

Die Schaltung ist dem Vorgänger sehr ähnlich und zeigt im Unterschied die neuen Anschlüsse für die hintere LED Leiste. Ebenfalls habe ich das Zusammenlöten der Komponenten so eingeplant, dass alles auf einer Platine Platz findet.

ATtiny45QuadrocopterLicht

Zusammengelötet und fast fertig auf der Platine.

Quadrocopter_09

Am Quellcode kann nun das Ansteuern des Pin 1 ergänzt werden. Damit wird später die hintere Lichtleiste ein- und ausgeschaltet.

// NeoPixel Bibliothek hinzufügen für die Ansteuerung der WS2812B LED Streifen
#include <Adafruit_NeoPixel.h>

// Instanz initialisieren
// Parameter Angaben:
// 1. Anzahl für verwendeter RGB LEDs
// 2. Auf welchen Pin soll verwendet werden.
// 3. Auswahl zwischen RGB, GRB oder BRG und verwendeter Takt 400KHz oder 800KHz

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(4, 2, NEO_GRB + NEO_KHZ800);

// Helligkeit einstellen. Kann von 0 bis Maximal 255 festgelegt werden.
// Bei Maximaler Ausleuchtung ist zu prüfen, ob die Maximale Stromabnahme erreicht wird.

int brightness = 100;

// Helligkeit bei verwendung der WS2812b, wenn sie weis auf blitzen sollen.
// Bei 210 wird die Maximale Stromabnahme überschritten.
// Darf nur kurz verwendet werden, ansonsten brennt der Spannungsregler durch.

int brightnessWhite = 210;

// Wird zum festlegen des Licht Einstellung verwendet.
// Damit die Einstellung funktioniert,
// muss an der Fernsteuerung einmal hin und her Geschaltet oder gedreht werden,
// um die längste Pulslänge zu ermitteln.

unsigned long maxPwmIn = 2;

void setup() {
  // Signal von der Fernsteuerung aufnehmen.
  pinMode(3, INPUT);
  // Positionslichter schalten
  pinMode(0, OUTPUT);
  // Neu. Um die LED Leiste ein- und auszuschalten.
 
pinMode(1, OUTPUT);
  // RGB LEDs Stribes starten
  pixels.begin();
  pixels.show();
}

void loop() {
  // Signal von der Fernsteuerung einlesen.
  // Für die Verwendung sollte ein Schalter genutzt werden.

  unsigned long pwmIn =  pulseIn(3, HIGH);
  // Wird zum Anlernen verwendet. Durch festlegen der maximalen Pulslänge
  // können zwei Zustände verwendet werden.

  if(pwmIn > maxPwmIn) { maxPwmIn = pwmIn; }
 
  // Wenn das Signal kürzer ist als der Maximalen Pulslänge.
  if(pwmIn < maxPwmIn - 100){
    // Positionslichter einschalten
    // (Bei verwendung von NPN Transisitor, kann die '255 -' weg)

    analogWrite(0, 255 - brightness); delay(100);
    // Ausschalten (Bei NPN, den Wert auf 0 setzen.)
    analogWrite(0, 255); delay(100);
    // Die LED Leiste einschalten
   
analogWrite(1, 255);
    // RGB LED Streifen ansteuern.
    // Rot und Grün

    allRGB_LED_Off();
    pixels.setPixelColor(0, pixels.Color(brightness, 0, 0));
    pixels.setPixelColor(1, pixels.Color(0, brightness, 0));
    pixels.show();
    delay(100);
    allRGB_LED_Off();
    pixels.setPixelColor(2, pixels.Color(brightness, 0, 0));
    pixels.setPixelColor(3, pixels.Color(0, brightness, 0));
    pixels.show();
   delay(100);
  }
  else
  {
    // Positionslichter ausschalten
    // (Bei verwendung von NPN Transisitor, ist zum Ausschalten der Wert 0)

    analogWrite(0, 255);
    // Die LED Leiste ausschalten.
   
analogWrite(1, 255);
   // RGB LED Streifen ansteuern.
    for(int i = 0; i < 4; i++)
    {
      // Alle aus.
      allRGB_LED_Off();
     // Mit der Aktuellen Iteration als Index verwenden,
      // um den entsprechende RGB LED zu überschreiben.

      pixels.setPixelColor(i, pixels.Color(brightnessWhite, brightnessWhite, brightnessWhite));
      pixels.show();
      delay(100);
    }
  }
}
// Stellt alle Werte zurück.
void allRGB_LED_Off()
{
  for(int i = 0; i < 4; i++)
  {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
  }
}

Zuletzt dürfen zur Demo die Videos nicht fehlen.

Sonntag, 19. April 2015

Beleuchtung mit dem ATtiny 45

image

Zuerst habe ich darüber nachgedacht, was ich alles an Beleuchtung am Quadrocopter anschließen möchte und kam zu dem Entschluss Positionslichter anzubringen. Das macht dann besonders Sinn, wenn der Quadrocopter bereits 40 Meter entfernt ist. Für diesen Zweck eignen sich ultrahelle LEDs ab einer Lichtstärke von über 5000mcd. Für das Bunte sah ich die WS2812B auf Streifen für die Unterbodenbeleuchtung. Diese RGB LEDs sind nicht nur leuchtstark, sondern können über eine Leitung angesteuert werden.

image

Normalweise würde ich einen ATMega328 oder 168 verwenden, doch die bessere Wahl ist ein ATtiny. Der ATTiny45/85 z.B. hat insgesamt acht Pins. Zwei für die Stromversorgung, einen für Reset und der Rest kann frei programmiert werden.

image

Für das Vorhaben werden folgende Teile benötigt:

  • 1x ATTiny45
  • 2x Ultrahelle LEDs Grün (3mm, 6000mcd)
  • 2x Ultrahelle LEDs Rot (3mm, 5000mcd)
  • RGB LEDs WS2812B
  • 2x PNP Transistoren (es gehen auch 2x NPN, muss nur im Code umgedreht werden)
  • 2x 22µF Kondensatoren (63V, darf auch niedriger sein)
  • 1x 5V Spannungsregler (UTC LP2950G 5.0 QC4, 160mA)
  • 2x 75 Ohm Widerstand (100Ohm kamen in meiner Schaltung)
  • 2x 2,2kOhm Wiederstände
  • 1x Rasterplatine
  • ausreichend Schrumpfschläuche
  • und natürlich dürfen die Kabel nicht fehlen

[Bild von den Teilen]

Bevor das Ganze zusammengelötet wird, empfiehlt sich ein Test der Schaltung auf dem Breadboard. In meinem Fall war dies auch notwendig, da die Anzahl der angeschlossen LEDs mehr Strom benötigt hat. Der vorgegebene Spannungsregler kann bis zu 160mA durchlassen und reicht für die grünen und roten LEDs auch aus. Kommen nun die RGB LEDs hinzu, dann wird es knapp. Selbst wenn jetzt die vier LEDs ca. 120mA verbrauchen, bleiben nur 40mA übrig. Das reicht gerade mal für zwei weitere LEDs, in einer RGB LED sind aber drei. Abgesehen davon, dass der ATtiny für die Ansteuerung der WS2812B verwendet wird, kann dieser auch die Ansteuerung der Helligkeit regulieren und somit den Stromverbrauch reduzieren. Hierbei werden die einzelnen LEDs mit einem PWM Signal angesteuert. Kommen wir zur Grundschaltung.

image
Schaltbild vom Versuchs- und Testaufbau.

Kommen wir nun zu dem ATtiny. Um diesen zu beschreiben verwende ich einfach einen Arduino und einen eigenen, selbst gelöteten Shield. Alternativ kann dies auch auf einem Breadboard zusammengesteckt werden.

image

Ich empfehle, die Arduino Entwicklungsumgebung zu verwenden; dies erspart weitere Kosten für ein neues Board. Das setzt natürlich voraus, dass man bereits einen Arduino besitzt.

Nachteil ist, dass für die Verwendung eine weitere Komponente installiert werden muss.

Die Seite high-low tech erklärt, wie der Arduino als ISP Programmer für den ATtiny verwendet werden kann. Daher fasse ich kurz zusammen, was für die Installation wichtig ist.

Nun fehlt noch eine Sache. Für die Verwendung der WS2812B RGB LEDs wäre eine wenig mehr Code notwendig. Ich greife deshalb auf eine fertige Library zurück. Diese wird von Adafruit bereit gestellt auf GitHub.com/adafruit/Adafruit_NeoPixel. Die fertige Bibliothek kommt diesmal in den Ordner ../Arduino/libraries/Adafruit_Neopixel.

Jetzt kann der eigentliche Spaß losgehen. Der folgende Beispiel Code ist extra kurz gehalten und geht mehr auf die verwendete Inhalte ein.

// NeoPixel Bibliothek hinzufügen für die Ansteuerung der WS2812B LED Streifen
#include <Adafruit_NeoPixel.h>

// Instanz initialisieren
// Parameter Angaben:
// 1. Anzahl für verwendeter RGB LEDs
// 2. Auf welchen Pin soll verwendet werden.
// 3. Auswahl zwischen RGB, GRB oder BRG und verwendeter Takt 400KHz oder 800KHz

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(4, 2, NEO_GRB + NEO_KHZ800);

// Helligkeit einstellen. Kann von 0 bis Maximal 255 festgelegt werden.
// Bei Maximaler Ausleuchtung ist zu prüfen, ob die Maximale Stromabnahme erreicht wird.

int brightness = 100;

// Helligkeit bei verwendung der WS2812b, wenn sie weis auf blitzen sollen.
// Bei 210 wird die Maximale Stromabnahme überschritten.
// Darf nur kurz verwendet werden, ansonsten brennt der Spannungsregler durch.

int brightnessWhite = 210;

// Wird zum festlegen des Licht Einstellung verwendet.
// Damit die Einstellung funktioniert,
// muss an der Fernsteuerung einmal hin und her Geschaltet oder gedreht werden,
// um die längste Pulslänge zu ermitteln.

unsigned long maxPwmIn = 2;

void setup() {
  // Signal von der Fernsteuerung aufnehmen.
  pinMode(3, INPUT);
  // Positionslichter schalten
  pinMode(0, OUTPUT);
 
  // RGB LEDs Stribes starten
  pixels.begin();
  pixels.show();
}

void loop() {
 
  // Signal von der Fernsteuerung einlesen.
  // Für die Verwendung sollte ein Schalter genutzt werden.

  unsigned long pwmIn =  pulseIn(3, HIGH);
  // Wird zum Anlernen verwendet. Durch festlegen der maximalen Pulslänge
  // können zwei Zustände verwendet werden.

  if(pwmIn > maxPwmIn) { maxPwmIn = pwmIn; }
 
  // Wenn das Signal kürzer ist als der Maximalen Pulslänge.
  if(pwmIn < maxPwmIn - 100){
    // Positionslichter einschalten
    // (Bei verwendung von NPN Transisitor, kann die '255 -' weg)

    analogWrite(0, 255 - brightness); delay(100);
   // Ausschalten (Bei NPN, den Wert auf 0 setzen.)
   analogWrite(0, 255); delay(100);
   
    // RGB LED Streifen ansteuern.
    // Rot und Grün

    allRGB_LED_Off();
    pixels.setPixelColor(0, pixels.Color(brightness, 0, 0));
    pixels.setPixelColor(1, pixels.Color(0, brightness, 0));
    pixels.show();
    delay(100);
    allRGB_LED_Off();
    pixels.setPixelColor(2, pixels.Color(brightness, 0, 0));
    pixels.setPixelColor(3, pixels.Color(0, brightness, 0));
    pixels.show();
   delay(100);
  }
  else
  {
    // Positionslichter ausschalten
    // (Bei verwendung von NPN Transisitor, ist zum Ausschalten der Wert 0)

    analogWrite(0, 255);
   
   // RGB LED Streifen ansteuern.
    for(int i = 0; i < 4; i++)
    {
      // Alle aus.
      allRGB_LED_Off();
     
     // Mit der Aktuellen Iteration als Index verwenden,
      // um den entsprechende RGB LED zu überschreiben.

      pixels.setPixelColor(i, pixels.Color(brightnessWhite, brightnessWhite, brightnessWhite));
      pixels.show();
      delay(100);
    }
  }
}

// Stellt alle Werte zurück.
void allRGB_LED_Off()
{
  for(int i = 0; i < 4; i++)
  {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
  }
}

Im folgendem Video wird gezeigt, wie dieses Code Beispiel aussieht. Daneben ist noch ein Netduino der ein PWM Signal abgibt und alle drei Sekunden wechselt zwischen 900 und 1100 Mikrosekunden Pulslänge, um das Umschalten zu simulieren.

Bei dem ATtiny45 wird man schnell feststellen, dass der Speicher sehr knapp ist. Wer mehr Lichtanimationen einsetzen möchte, sollte auf einen ATtiny85 wechseln. Und wer mehr Licht einsetzen und nicht unbedingt an Strom sparen will, wird einen größeren Spannungsregler benötigen.

 Referenzen

Quadrupes Simulation nochmal von vorne

  Die erste Version von der Simulation hatte ich mit Claude Sonnet 5.5 generiert und die war in Ordnung, aber nicht das was ich mir eige...