Adruino als ISP

Die Arduino Plattform (Hard und Software) eignet sich hervorragend für Projekte aller Art.
Ab und an möchte man jedoch nur den Controller in die eigene Schaltung einsetzen.
Was viele nicht wissen: Der Arduinokann mit einem Sketch in einen ISP programmieradapter verwandelt werden und somit können auch kleinere Atmel Prozessoren programmiert werden.

 

Als erstes ist der Arduino (UNO) als ISP zu programmieren. Dazu wird ein Sketch als Example mitgeliefert.

Folgende Verbindungen sind herzustellen
Achtung!
Hier sind die physischen PIN's
des IC gemeint!

ATtiny85
D10 -- Pin 1  RST
D11 -- Pin 5  MOSI
D12 -- Pin 6  MISO
D13 -- Pin 7  SCK

ATtiny85
D10 -- Pin 4   RST
D11 -- Pin 7   MOSI
D12 -- Pin 8   MISO
D13 -- Pin 9   SCK

Datenblatt ATtiny85

Datenblatt ATTiny44

m Internet gibt es ZIP Files wo diverse Tiny Typen in Headerfiles etc. Arduino like konfiguriert sind. Dies sind herunterzuladen und in das Hardwareverzeichnis zu kopieren.So dann erscheinen auch mehere Tiny Typen zur Auswahl 

Als nächstes ist der Programmer auf Arduino as ISP einszustellen und der zu programmierende ATtiny auszuwählen.

 

Nun ist es an der Zeit den Sketch für den Tiny hochzulade. Die hier gezeigte Fehlermeldung kann getrost ignoriert werden.

 

AT Tiny 433Mhz Schneehöhenmessgerät

Energie und Platzsparender Sender für "beliebige" Messwerte oder auch zur Überwachung von Kontakten und Zuständen aller Art

Programmierung eines Tiny Controllers

Die Programmierung erfolgt mit Hilfe eines Arduino UNO Boards, welches Adruino als ISP.

Eigentliche Schaltung

Diese besteht aus der Stromversorgung (3,3V)
aus dem Tiny,
und aus demFunkmodul

Ausserdem brauchen wir natürlich noch den Ultraschallsensor zur Entfernungsmessung.

Verbesserungen

Möglich wäre in diesem Zusammenhang noch die Überwachung der Batteriespannung um den Batteriewechsel frühzeitig zu erkennen.

Auswertung des Funksignals

Die Auswertung der Funksignale erfolgt derzeit mit einer Erweiterung meines SmartHome Gateways .
Dieses habe ich um einen 433Mhz Empänger erweitert.

Das so empfangene Funksignal wird mit Hilfe der DeviceId (siehe Quellcode) eindeutig einer Messstelle zugeordnet und als UDP Broadcast
auf das LAN-Netz gegeben. Dort lauscht ein Raspberry Pi am entsprechenden Socket, welcher die Werte in eine MySql Datenbank wegschreibt. 

Ein Auswerteprozess (WEB Seite) kann dann die Messwerte (Schneehöhe) lesen und als Diaramm oä. darstellen. WinkenSoweit bin ich allerdings noch nicht

 

Software- und Schaltungstricks

Um nun besonders Stromsparend "unterwegs" zu sein, beherscht der Tiny verschiedne Sleep Mode.
In diesem Mode, verbraucht er so gut wie keinen Strom. Die "Kunst" besteht nun darin den Tiny zu definieren Zeitpunkten zu wecken, die Messung und Funkübertragung zu machen und ihn sofort danach wieder "schalfen zu legen".

Da der Tiny nicht durch einen Timer aus dem Sleep erweckt werden kann, muss diese Aufgabe der WatchdogInterrupt erledigen. Da dieser wiederum aber auf max. 8sec.  eingestellt werden kann, brachen wir noch eine Schleife "außen rum" (siehe GlobalSleep() im Quellcode ).

Quellcode

Die Funktionen InitWatchdog und GlobalSleep hab ich im Internet als Anregung gesehen und entsprechnd angepasst. Leider weis ich die Herkunft nicht mehr. Sollte sich der Authr wiederfinden, bitte kurze Mail an mich, dann wird dieser selbverständlich genannt!

#include "RCSwitch.h"
#include "xrc.h"
#include
#include

#define PinIn    1        //PulsePin
#define PinTx    4        //Sender
#define PinPing  3        //Trigger

#define DeviceID       10 //Gerätekennung
#define SendDelay       1 //Sendeintervall 8 * 7 = 56s

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

//Interrupt Flag für WakeUp from Sleep Mode
volatile boolean f_wdt = 1;
ISR(WDT_vect) {f_wdt=1;}

//Sender instanzieren
XRC RC = XRC();

//Hauptprogramm (Initialisierung)
void setup()
{
  //Sender Initialisiseren (kein Tx, Sender an Pin 4)
  RC.begin(-1,PinTx);

  //Sonstige Initialisierung
  pinMode(PinPing, OUTPUT);
  digitalWrite(PinPing, LOW);  
  pinMode(PinIn,   INPUT);

  //Sleep and Watchdog initialisieren
  InitWatchdog();     //Watchdog für 8sec Starten
}

//Programmschleife
void loop()
{
  //Messwerte besorgen
  uint16_t value = GetDistance();
 
  //Wert senden
  RC.send(DeviceID, value);

  //Deep Sleep!   CPU(5V) = 7uA!  CPU(3.3V) = 4uA!
  //mit Sensor 7mA bei 5V
  GlobalSleep();
}

//#################################################################
long GetDistance()
{ //                      |<-distance->|
  // PinPing: __----------__________________________
  // PinIn  : xxxxxxxxxxxx_____________---------____
 
  digitalWrite(PinPing, HIGH);
  delayMicroseconds(10);
  digitalWrite(PinPing, LOW);

  long pingDuration = pulseIn(PinIn, HIGH);
  return (pingDuration / 29 / 2);   //Wert in cm
}

//#################################################################

//All Power Off - WakeUp from Watchdog INT (Statment )
void GlobalSleep()
{
  for (uint8_t sleepCounter= 0; sleepCounter < SendDelay; sleepCounter++)
  {
    if (f_wdt==1)
    {  // wait for timed out watchdog / flag is set when a watchdog timeout occurs
      f_wdt=0;       // reset flag
      cbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter OFF
      set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
      sleep_enable();
      sleep_mode();                        // SLEEP!
      sleep_disable();                     // System continues execution here when watchdog timed out
      sbi(ADCSRA,ADEN);                    // switch Analog to Digitalconverter ON
    }
  }
}

//ii..0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void InitWatchdog()
{
  byte bb;
  bb = 9 & 7;
  bb|= (1<<5);
  bb|= (1<   MCUSR &= ~(1<  
  // start timed sequence
  WDTCR |= (1<  
  // set new watchdog timeout value
  WDTCR = bb;
  WDTCR |= _BV(WDIE);
}

Universeller 8 Kanal (Analog/Digital) FS20 Sender.

Bei Interesse nehmen Sie Bitte Kontakt mit mir auf (Es ist jedoch nicht möglich den Quellcode einzeln weiterzugeben).

PDF Beschreibung PDF Beschreibung

 

 

Arduino Nano oder kompatibleFS20 US

Feature

  •   4 Digitale Eingänge abfragen
  •   4 Analoge Eingänge als Trigger abfragen
  •   4 x Analogwert Aussendung mittels FS20 Protokoll
  •   Verknüpfungslogik aller Eingänge mittels AND möglich
  •   Verknüpfungslogik aller Eingänge mittels OR möglich
  •   Einstellung der  Entprellzeit und der Anzahl der Abfragen pro „Durchlauf“
  •   Für alle Kanäle gleicher, einstellbarer Hauscode

Digitale Eingänge

Es stehen 4 digitale Eingänge zur Verfügung. Jeder Eingang kann separat konfiguriert werden.
Es ist ein Schalten bei HIGH (ON) und/oder LOW (OFF) möglich. Außerdem kann der Eingang im TOGGLE Betrieb genutzt werden. Das heißt beim ersten „schalten“ werden die ON und beim zweiten schalten die OFF Einstellungen benutzt, usw.

Für ON und OFF getrennt einstellbar ist die Kommandowiederholung (RPT) in Minuten (1…255).

Analoge Eingänge

Es stehen 4 analoge Eingänge zur Verfügung. Jeder Eingang kann separat konfiguriert werden.
Es ist ein Schalten bei HIGH (ON) und/oder LOW (OFF) möglich.  Die Schaltschwelle (Triggerpunkt) zwischen ON und OFF kann als Prozentwert konfiguriert werden.

Als besonderes Feature ist es möglich den prozentualen Analogwert, als Messwert über FS20 zu übertragen (VAL Mode). Dazu wird das ON Kommando benutzt. Im EXT Byte des Funktelegramms wird der Wert übertragen.
Achtung (nicht 100% kompatibel zu FS20 Spezifikation)! Nicht alle Kommandos unterstützen alle Werte im EXT Feld. Der Empfänger muss mit diesem Byte natürlich auch etwas anfangen können.

Für ON und OFF getrennt einstellbar ist die Kommandowiederholung (RPT) in Minuten (1…255).

FS20 Feuchtesensor (Nano)

Anwendungsbeispiel für den FS20 Universalsender

Der hier abgebildete Sensor misst die Bodenfeuchte und überträgt diese mittels FS20 Funkmodul ANALOG! an einen Rasperry Pi, welcher diese in eine MySQL Datenbank einträgt.

Um auch einen langen Batteriebetrieb zu gewährleisten, habe ich mich entschieden eine Hardwarelösung zu bauen. Dies schaltet ca. aller 30min die Spannung zu. Daraufhin führt der Arduino seine Messung und Übertragung durch und schaltet danach den Strom wieder ab.

So komme ich auf eine Baterielaufzeit von knapp einem Jahr, bei ca. 50 Messungen pro Tag.

 Außerdem misst der Arduino noch die Batteriespannung. singt diese unter ein einstellbares Level, wird ebenfalls eine FS20 Nachricht versendet.

 

 

Ringer

Hierbei handelt es sich um ein Zutrittskontrollsystem im weitesten Sinne mit den Funktionen Ein- und Ausschalten der Alarmanlage, sowie abbilden der Klingel Funktion.
 

Zum Einsatz kommt ein Arduino Nano. Dieser ist mit enem NFC Shied über I2C verbunde. Die Anzeige verschiedener Informationen geschieht über ein 8x8 LED Shield (MAX7219), welches über ein SPI ähnliches protokoll kommuniziert. 

Leider waren am Installationsort nur 2 Anschlussadern vorhanden (5V, Masse). Daher erfolgt die Kommunikation mit der "restlichen" Haussteuerung über ein WLAN Modul --ESP8266-- (ist auf dem Bild nicht zu sehen, da LED Modul verdeckt). Da dieses Modul mit 3,3V arbeitet, ist auch noch ein diesbezüglicher größerer Spannungswandler notwendig (300mA Strom notwendig). Die Kühlfahne ist zwischen LED Modul und NFC Shield ansatzweis zu sehen.

Leider war es so das die im Internet vorhandenen Libraries für das LED Modul nicht benutzbar war. Die mir zur Verfügung stehende Library hatte einen viel zu hohen Speicherverbrauch (RAM). Durch definitionen wie int8_t  matrix[8][8]  sind gleich mal 64 Byte belegt, wird das dann auch noch einer Funktion übergeben (nicht per Referenz), so werden diese auch noch mal auf den Stapel gelegt.
Als Konsequenz daraus habe ich eine vollkommen neue Library geschieben (RAM ca. 15Byte). Bei dieser Gelegenheit habe ich auch noch Funktionen, wie:  Scrollen, Rotation und Zeichensatz im EPROM ablegen implementiert.

void setRotation(uint8_t grad);   //0...0,1...90,2...180,3...270
void setNumber(int8_t num);
void put(char c, uint8_t offset=0);
void print(char *msg);
void shift(uint8_t offset);

Library ESP8266

Auch bei der Library des WLAN Moduls habe ich einige Optimierungen vorgenommen (vor allem wegen des Speicherbedarfs). So wird in der original Lib, sehr sorglos mit den STRING Objecten umgegangen. Ich habe das lles auch char[] umgestellt. Ausserdem musste ich den Funktionsumfang für meine Zwecke kürzen.

void Reset();
void BeginWifiStation(...);
void BeginTcpServer();
void SendUDP(uint8_t mux, uint32_t port,char *msg);
void SendTCP(uint8_t mux, char *msg);
void Close(uint8_t mux);
uint16_t Receive(...);
int8_t GetWiFiSnr();

Wichtig beim Einsatz des ESP8266  an einer SoftSerial Schnittstelle ist, dass diese scheinbar nicht stabil mit 115200Baud umgehen kann!
Ich habe daher das Modul auf 9600 umgestellt und die Schnittstelle antürlich ebenfalls so betrieben.

 

Hardware

Beim Betrieb des NFC Shields an I2C stellte sich heraus, dass es manchmal nach einem Neustart des Arduino (Reset) zu Situationen kommt, wo das Shield "hängt". Diese Situation tritt immer dann auf, wenn das Reset wärend einer aktiven I2C Kommunikation stattfindet. Da das Shild von dem Reset nichts mitbekommt, fällt die Kommunikation auseinander".
Als Lösung dafür habe ich eine seperate Leitung von einem Arduino PIN an den Reset "Fuß" des HCOM Interfaces (oberes Bild linke Lötleiste ganz oben) "gezogen". Durch einen kurzen (50ms) Low-Impuls in der Setup Routine, wird das Modul in den Ausgangszustand versetzt. In der Folge traten solche "Hänger" nicht mehr auf.

   
© ALLROUNDER