Hier findet ihr das fertige Projekt wesentlich übersichtlicher: [Messen, Steuern, Regeln] Batteriebetriebene Funk Sensoren
Vorläufige Zusammenfassung/Beschreibung der TinyTX4 Sender- und Empfänger-Platinen von der Sammelbestellung findet ihr in Beitrag#675
Vorwort:
Das hier ist nur der Entwicklungs-Thread in denen die Informationen gesammelt und Fortschritte usw gepostet werden
Wenn das Projekt fertig entwickelt ist werde ich einen neuen Thread mit der entgültigen Version sowie alle benötigten Informationen erstellen!
Nachfolgendes ist noch nicht fertig, möchte ich aber hier aus diesem Thread schon mal zusammentragen damits ein bischen übersichtlicher wird
Ziel dieses Projekts ist es schnurlose Funk Sensoren, die über Batterien versorgt werden, zu betreiben und mit dem RaspberryPI die Daten zu empfangen sowie auszuwerten.
Als Sensor kann man theoretisch so ziemlich alles verwenden, ob Temperature / Luftfeuchtigkeit oder Magnetschalter / ReedKontakt usw
Das Projekt orientiert sich am TinyTX von Nathan Chantrell (auf der Seite findet ihr auch weitere Informationen zu verwendbaren Sensoren)
Technische Grundlagen:
Zur Funkübertragung habe ich mich für RFM12B Module entschieden da diese sehr klein, stromsparend, flexibel aber vorallem auch in Deutschland zulässig sind (und man auf bereits vorhandene Libs zurück greifen kann).
Die Übertragung erfolgt dabei über das ISM-Band und wahlweise 433MHz oder 868MHz (zwei verschiedene Module).
Das RFM12B hat eine Betriebsspannung von 2.2V bis 3.8V, funktioniert aber problemlos auch mit bis zu 6V und wird dadurch auch (angeblich) nicht beschädigt - habe es selber problemlos längere Zeit mit 5V betrieben aber keine negativen Auswirkungen feststellen können.
Gesteuert wird das ganze über einen ebenfalls sehr stromsparenden Atmel Microcontroller Chip ATtiny84A-PU der ebenfalls sehr klein und stromsparend ist. Man könnte aber auch einen Atmel Mega nutzen wenn man zB mehr Speicher oder Pins benötigt.. Aufgrund der begrenzten Flash-Speichergröße (8 kB) des ATtiny84A können die Sketches leider nicht allzu umfangreich ausfallen, für die hier genutzten Zwecke ist es aber ausreichend
Der ATtiny84A hat eine Betriebsspannung von 1.8V bis 5.5V .. Da er hiefür aber mit 8 MHz betrieben werden muss liegt die Betriebsspannung bei 2.7V bis 5.5V
Als Stromversorgung verwende ich 3 x AA Batterien, die im geladenen Zustand eine Spannung von ca. 4.5V liefern (eine hat 1.5V). AA Batterien sind eine bessere Wahl als AAA, denn damit ist ein längerer Betrieb möglich da die eine höhere Kapazität haben.
Im leeren Zustand beträgt die Spannung einer Batterie noch etwa 0.9V bis 1.0V, was also bedeuten würde das bei 3 Batterien noch eine Spannung von ca. 3V angezeigt werden würde.. Das RFM12B Module benötigt mindestens 2.2V und der ATtiny64A mindestens 2.7V - demnach wäre es mit 3 Batterien noch im grünen Bereich. Allerdings nimmt dann selbstverständlich die Reiche ab, da nicht mehr genug Ampere zur Verfügung stehen.. Deshalb plane ich auch ein Hinweis in die Graphen-Page einzubauen sobald ein Sensor längere Zeit keine Daten mehr übertragen hat, denn die Sensoren übermittelt zusätzlich zu den eigentlichen Werten auch die aktuelle Spannung ihrer Stromversorgung (Supply Voltage). Dadurch liese sich erkennen wann die Batterien ausgetauscht werden müssten..
Bei den Sensoren sollten Digitale bevorzugt werden da man dann keinen Analog-to-Digital-Wandler benötigt und dies somit auch weniger Code und Strom benötigt.
Zusätzlich zu den oben genannten Bauteilen benötigt man auch noch ein paar Widerstande und Keramik-Kondensatoren, sowie einen Sockel für den ATtiny Chip, ein bischen Kabel und einen Kupferdraht für die Antenne des RFM12B Modules. Um das alles irgendwie zusammen zu löten verwende ich eine Streifenrasterplatine.
Hinweise:
- Nach einigen Tests scheint der Empfänger unbedingt die NodeID 22 haben zu müssen damit es funktioniert! Wieso das so ist konnte ich bisher nicht herausfinden. Die Sender können aber nach belieben eine NodeID von 1 bis 30 haben (also insg. 29 Sender)
- Wichtig ist auch die Wahl der richtigen Batterie, was sowohl Größe (AA oder AAA) als auch Kapazität betrifft. Es muss auch darauf geachtet werden das die maximalen Spannungen der hier verwendeten Bauteile nicht überschritten werden. Also die Anzahl der Batterien nicht über 3 liegen sollte, da die Batterien in Reihe geschaltet werden und sich somit die Spannung addiert (zB 3 x 1,5V = 4,5V). Wie lange die Batterien halten hängt aber natürlich auch vom Intervall der Datenübermittlung ab: Alle 60 Sekunden oder alle 300 Sekunden macht schon einen nicht zu unterschätzenden Unterschied aus.
- 10µH Drosseln (Spulen) sind in ihrer Bauform so groß wie Widerstände. In den AVR-Eingangsbeschaltungen werden sie nur benötigt, um Störimpulse zu unterdrücken (tiefpassfilter) .
Die Reichweite
Oft werde ich gefragt: “Wie weit gehen die denn?” Diese Frage lässt sich nicht mit einer einfachen Angabe von x km beantworten.
Die erzielbare Reichweite aller Funklösungen ist hauptsächlich abhängig von der Antenne, Antennenaufstellungsort, Empfängerempfindlichkeit, Sendeleistung und der Frequenz.
Auf die Empfängerempfindlichkeit haben wir meist keinen Einfluss.. Wir konzentrieren uns also auf die Antenne und die Frequenz.
Für mobile Lösungen setzen wir kurze (ca.50 mm) oder lange (100 bis 200 mm), auf die Frequenz abgestimmte Stabantennen ein. Die Antennen sollten möglichst parallel angeordnet sein, was aber beim Kopter meist nicht der Fall ist.
Wenn es weiter reichen soll müssen wir bei der Bodenstation mit einer Richtantenne arbeiten. Bei einem Modul mit 25 mW Leistung auf 868 MHz können wir damit die Reichweite von ca. 800 m auf über 4 km erhöhen.
Bei der Frequenz gilt: je tiefer desto besser.
Zum Beispiel ein XBee mit 100mW auf 2,4 GHz sieht alt aus, verglichen mit 10 mW auf 433 MHz. Hier haben wir bei der Wahl der Module den größten Einfluss auf die erzielbare Reichweite.
Die maximal erlaubte Sendeleistung ist länderspezifisch.
Die maximale zugelassene Sendeleistung mit einem Duty cycle von 100 % beträgt bei 433 MHz ERP 10 mW, bei 868 MHz dürfen es 25 mW sein.
Mit dem 433 MHz Funkmodul lassen sich, aufgrund der besseren Ausbreitungsbedingungen, enorme Reichweiten erzielen. Aber auch das 868 MHz Modul schlägt das 433Mhz Module in der maximalen Reichweite.
Es gibt Module für die ISM Frequenzen 433/470/868 und 915 MHz. Hier in Europa sind allerdings nur die Frequenzen 433 MHz und 868 MHz interessant bzw zugelassen.
Ein paar genauere Details zu den RFM12 Modulen kann man auch hier (auf Englisch) nachlesen: http://blog.strobotics.com.au/…/17/rfm12-tutorial-part2/
Oder hier ein Vergleich zwischen RFM12, RFM22 und RFM23: http://blog.strobotics.com.au/…g-brothers-to-the-rfm12b/
Nachfolgend noch mal eine genaue Bauteil-Liste der benötigten Teile:
pro Sender-Sensor:
Basis:
- Atmel ATtiny 84V-10PU (Low-Voltage) - oder besser: ATtiny 84A-PU (Pico-Power) .. plus Sockel (um die AVR Chips später ggf neu programmieren zu können)
- RFM12B Funkmodule (433Mhz oder 868Mhz, 2.2V-3.8V)
- 2x AA / AAA Batterie Halter für ATtiny 84V-10PU, oder 3x AA / AAA für ATtiny 84A-PU
- Streifenplatine: 15 x 16 Löcher
- Plastikgehäuse (50x50x20mm müsste theoretisch reichen)
- Kupfer/Klingel-Draht für 165mm lange 1/4W Antenne (allgemeine detailierte Beschreibung)
- 1x 10µH Spule zwischen 5V und AVcc [für bessere Messwerte]
- 2x 100nF Keramikkondensator zwischen GND und Vcc (Pin 11 und 10) und zwischen AVcc und GND (30 und 31) [für bessere Messwerte]
Je nach verwendetem Sensor:
- DS18B20 - Digital Temperatur Sensor + 4,7k Ω Widerstand
- DHT22 - Digital Temperatur&Luftfeuchtigkeits Sensor + 10k Ω Widerstand (liefert bei einer Spannung unter 2,96V falsche Werte)
- TMP36 - Analog Temperatur Sensor, ohne Widerstand (2,7V - 5,5V). Wichtiger Hinweis zum TMP36 > hier <.
- BMP085 - Digitaler Temperatur & Luftdruck & Höhen Sensor (1,8V - 3,6V) (liefert genauere Werte als DHT22)
- LDR - Analoger Licht Sensor (Fotowiderstand) + 10k Widerstand
Optional:
- 3 pol Buchsenleiste - oder 3 pol Stiftleiste plus Pfostenstecker ... für austauschbaren Sensor
- 2 pol Buchsenleiste - oder 2 pol Stiftleiste plus Pfostenstecker ... für austauschbaren Widerstand
Empfänger:
Bei dem Empfänger würde ein Sensor und somit auch die Spulen wegfallen, aber trotzdem sollten die Kondensatoren auch hier verbaut werden. Zusätzlich werden aber auch noch 2x 10k Ω Widerstände benötigt
Antennenlänge, sowie ein Bild zur Verlötung des RFM12B Modules auf eine Streifenrasterplatine wird > hier < beschrieben.
Reichelt Warenkorb für 5 Sensoren - exkl. AVR & Sensor & Funkmodule: http://www.reichelt.de/?ACTION=20;AWKID=821034;PROVID=2084 .. Warenkorb-Kosten: 17,51eu plus 5,60eu VSK
Ansonsten die Bauteile einzeln bestellen, nachfolgend eine kleine Ansammlung:
5x ATtiny 84A-PU über eBay für insg. 6,99eu plus 1,80eu VSK ... einer kostet dann 1,758eu inkl. VSK
Alternative:
ATtiny 84A-PU über guloshop.de .. für je 1,00eu plus 2,40eu VSK ... bei 5 Stück würde einer 1,48eu inkl. VSK kosten (2,40eu VSK bis 10eu Warenwert, über 10eu: 4,80eu VSK)
10x IC Sockel 14 polig über ebay für 1,00eu plus 1,75eu VSK
DS18B20 über amazon (Affiliate-Link) ... 5 Stück für 6,79eu inkl. VSK
DHT22 über eBay .. für je 4,48eu inkl. VSK
TMP36 über eBay .. 2stk. für insg. 3,53eu plus 1,85eu VSK
RFM12B 433Mhz Transceiver Sende Emfangs Modul über eBay .. für je 6,45eu plus 0,95eu VSK .. 5 Stück würden 38,70eu kosten (plus 1x VSK)
RFM12B 868Mhz Transceiver Sende Emfangs Modul über eBay .. für je 6,45eu plus 0,95eu VSK
Alternativ:
6x 433Mhz von JeeLabs für insg. 29,50eu (einzelpreis normalerweise: 6,50eu) plus 3eu VSK .. einer kostet dann 5,416eu inkl. VSK
6x 868Mhz von JeeLabs für insg. 29,50eu (einzelpreis normalerweise: 6,00eu) plus 3eu VSK
oder:
RFM02 433Mhz Transmitter Sende Modul über eBay .. für je 4,85eu plus 0,95eu VSK .. 5 Stück würden 24,25eu kosten (plus 1x VSK)
RFM02 868Mhz Transmitter Sende Modul über eBay .. für je 4,85eu plus 0,95eu VSK
Es gibt verschiedene RFM12 Module also Vorsicht:
RFM12B von HopeRF -> http://www.hoperf.com/rf_fsk/fsk/21.htm
Die haben eine Betriebsspannung von 2.2V bis 3.8V
RFM12 von Pollin -> http://www.pollin.de/shop/dt/N…_Sende_Empfangsmodul.html
Die haben eine Betriebsspannung von 2.2V bis 5.4V
Beide Module haben aber laut Datenblatt eine maximal zulässige Vdd Spannung von 6V
Kupferdraht über eBay, 1x10m (0,80mm²) .. für 1,69eu plus 1,90eu VSK
100nF Keramik Kondensatoren über ebay ... 20 Stück für 1,88eu inkl. VSK
oder:
100nF Keramik Kondensatoren über ebay ... 100 Stück für 3,09eu inkl. VSK
10k Ω Widerstände über ebay ... Metallschicht, 100 Stück für 2,79eu plus 1eu VSK
(ob Kohleschicht oder Metallschicht ist relativ egal. Metallschicht haben eine niedrigere Toleranz, sind höher belastbar und geringeres rauschen aber mittlerweile nur minimal teurer als Kohleschicht..)
AAA Batterien über Pearl ... 20 Stück für 3,90eu ... Spannung: 1,5 V , Kapazität: 1250 mAh
oder
AA Batterien über Pearl ... 20 Stück für 3,90eu ... Spannung: 1,5 V , Kapazität: 2800 mAh
2x AA Batterie-Halter geschlossen mit Ein-/Aus-Schalter über amazon (Affiliate-Link) ... für 1,15eu
3x AA Batterie-Halter geschlossen mit Ein-/Aus-Schalter über amazon (Affiliate-Link) ... für 2,10eu
3x AAA Batterie-Halter geschlossen mit Ein-/Aus-Schalter über amazon (Affiliate-Link) ... für 2,19eu
3x AAA Batterie-Halter geschlossen über amazon (Affiliate-Link) ... für 1,38eu
10x Single Reihe Stift- und Buchsenleiste über amazon (Affiliate-Link) ... für 4,98eu
Kosten für ein Sender-Sensor (berechnet für insg. 5 Module) liegt zwischen 12,43eu und 16,79eu (jenachdem wo oder was man aus der obigen Liste bestellt)
Für die Sender gäbe es auch fertige (nackte) Platinen die man aber erst in Auftrag geben müsste und Verhältnismässig viel kosten: http://www.circuits.io/circuits/1932 ... 3 x nackte PCB's für $15,21 inkl. VSK
Oder nachfolgendes lesen bzw nach dem Quote: (wäre wesendlich günstiger aber ist eben auch etwas umständlicher)
Quote
If you want to get PCBs made up I can recommend the Chinese site SeeedStudio, for 10 boards in green (other colours are more expensive) it costs 9.90 USD + shipping which worked out at £9.01 including UK delivery (90p each) and it will only take a couple of weeks. They don’t take Eagle files directly but Eagle can export the Gerber files that they need and they have an Eagle design rules file that makes it easy to check that your board fits with what they are capable of producing and a job file for the Gerber export to make sure everything is setup correctly for them. It’s still worth double checking the resulting Gerber files in a viewer such as Gerbv to make sure everything has come out as intended, I found that some of the silkscreen text that looked fine in Eagle had overflowed the board in the Gerber files. If you don’t want to get 10 boards made up you could always build the stripboard version or the guys at Circuits.io were also kind enough to import the Eagle files into their site for me so you can order boards in a pack of 3 from them for $14.67 plus $5 for international shipping. Unfortunately they don’t support adding text to the silkscreen so you will lose all the labelling with their boards. I’m not selling any boards myself at the moment but might have something in the pipeline soon.
Siehe dazu auch > hier < bzw im folgenden Spoiler:
Über http://iteadstudio.com
Oben im Menü auf OPEN PCB dann links auf PCB prototyping anschliesend:
PRICE: $0.00 - $9.99
PCB QUANTITY: 10 pcs
Smaller than 5cm x 5cm
Und dann rechts auf ADD TO CART ... anschliesend:
http://imall.iteadstudio.com/im120418001.html
Es kommen dann noch $3,90 Versandkosten für den Standardversand hinzu - also insg. $13,80 für 10 nackte Platinen
Nach Bestellung erhaltet ihr eine Bestätigungsmail.
Nun müsst ihr leider die Eagle Dateien vom Empfänger noch in Gerber Dateien umwandeln (wie das geht wird hier beschrieben (runter scrollen bis 'Gerber Files' erwähnt wird) - oder die RFM2Pi_rev3_gerber.zip von mir nutzen)
Vom Sender (TinyTX v3) gibt es bereits Gerber Dateien.
Anschliesend die Gerber Dateien, von der PCB die ihr haben wollt (entweder, oder) in einem gepackten Zip mit folgenden Dateinamen an die Adresse pcb@iteadstudio.com mailen:
<eure.OrderID>_pcb.zip
Ersetzt dabei <eure.OrderID> mit eurer OrderID also zB: 0123456789
Leider kann man pro Order nur jeweils Sender oder Empfänger beauftragen - wer also die Empfänger-Platine haben möchte muss sich 10 Stück davon anfertigen lassen!
Wenn ihr "Open Source" auf Yes gestellt habt, bedeutet das dass ihr 10 eurer bestellten Platinen kriegt und eure 2 zusätzlich jemand X-beliebiges der auch bei ITeadStudio bestellt - ihr kriegt stattdessen 2 andere Platinen (ich hab zB einmal Arduino Leonardo und ein mal Iteaduino BT 1.1 gekriegt - nur die Platinen - ohne Aufpreis).
Alle Platinen sehen übrigends sehr gut und hochwertig aus.
QuoteDisplay More
Prototyping PCB Order Steps:
1. Purchase Prototyping PCB Service from depot and check out.
2. An order number will be provided in confirmation email from iStore (info@iteadstudio.com)
3. Send the gerber file to pcb@iteadstudio.com with the order number in title - this file will be processed and please make sure it's your final design.
4. If the file and design meets requirements, they will be processed and shipped in 4-6 days, and we will not reply you. If the files have any issue pcb@iteadstudio.com will contact you.
Hier meine EMail die ich schrieb:
QuoteDisplay More
My Order Numer: ...
I've selected "Open Source: Yes" so i'll guess to get 2 additional pcs
Please use the attached Files:
1 x PCB of: ...__1_PCS.zip (RFM2Pi_rev3)
11 x PCBs of: ...__11_PCS.zip (tinytx3)
If this is not possible than please inform me befor you process
Thanks!
Den Receiver kann man auch fertig bestellen: http://shop.openenergymonitor.…berry-pi-expansion-board/ für 20,78eu plus 4,15eu VSK ...
Oder: http://jeelabs.com/products/rfm12b-board für 11,50eu plus 3eu VSK (funktioniert nur mit Arduino's!)
Oder mit den selben Bauteilen wie für den Sender selber löten, nur das kein Sensor verbaut wird
Zum Programmieren der ATtiny 84A-PU AVR's entweder den RaspberryPI benutzen
Oder: Arduino UNO rev3 über eBay .. für 12,99eu inkl. VSK (funktioniert besser, schneller und ist bequemer)
Wie, steht weiter unten..
Stripboard Plan für Sender Sensoren:
Stripboard Plan für Empfänger:
quelle: http://harizanov.com/wiki/wiki-home/rfm2pi-board/
fritzing Plan: fritzing_RFM12B.RX.zip
Zum flashen des ATtiny84a (mit 14 Pins) über den RaspberryPI folgendermassen über ein Steckbrett verkabeln:
(unbedingt den RPI ausschalten zum verdrahten! (spannungsspitze an RESET kann den Chip beschädigen)
AVR RESET (pin4) --> GPIO-8 (pin24)
AVR SCK (pin9) --> GPIO-11 (pin23)
AVR MOSI (pin7) --> GPIO-10 (pin19)
AVR MISO (pin8) --> GPIO-9 (pin 21)
AVR VCC (pin1) --> 3V3
AVR GND (pin14) --> GND
Anschluss-Plan:
quelle: http://blog.stevemarple.co.uk/…isp-programmer-using.html
- Benötigte Pakete installieren:Code
wget http://project-downloads.drogon.net/files/avrdude_5.10-4_armhf.deb wget http://project-downloads.drogon.net/files/avrdude-doc_5.10-4_all.deb dpkg -i avrdude_5.10-4_armhf.deb dpkg -i avrdude-doc_5.10-4_all.deb apt-get install arduino git-core gcc-avr lxde
- Optional: Signatur des Chips prüfen:
- Folgende Verzeichnisse erstellen:Code
mkdir -p /root/sketchbook/hardware/tiny/variants/tiny8 mkdir -p /root/sketchbook/hardware/tiny/variants/tiny14 mkdir -p /root/sketchbook/libraries
- RFM12B lib laden:
- JeeLib laden:
-
arduino-tiny-0150-0018.zip laden und entpacken:Code
cd /root/sketchbook/hardware/ wget http://arduino-tiny.googlecode.com/files/arduino-tiny-0150-0018.zip unzip arduino-tiny-0150-0018.zip && rm arduino-tiny-0150-0018.zip
- Folgende Dateien anlegen:
-
/root/sketchbook/hardware/attiny/boards.txtCode
Display Moreattiny84at8.name=ATtiny84 @ 8 MHz (internal oscillator; BOD disabled) # The following do NOT work... # attiny84at8.upload.using=avrispv2 # attiny84at8.upload.using=Pololu USB AVR Programmer # The following DO work (pick one)... attiny84at8.upload.using=arduino:arduinoisp # attiny84at8.upload.protocol=avrispv2 # attiny84at8.upload.using=pololu attiny84at8.upload.maximum_size=8192 # Default clock (slowly rising power; long delay to clock; 8 MHz internal) # Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms; [CKSEL=0010 SUT=10]; default value # Brown-out detection disabled; [BODLEVEL=111] # Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0] attiny84at8.bootloader.low_fuses=0xE2 attiny84at8.bootloader.high_fuses=0xD7 attiny84at8.bootloader.extended_fuses=0xFF attiny84at8.bootloader.path=empty attiny84at8.bootloader.file=empty84at8.hex attiny84at8.build.mcu=attiny84 attiny84at8.build.f_cpu=8000000L attiny84at8.build.core=tiny ########################################################################### attiny84at1.name=ATtiny84 @ 1 MHz (internal oscillator; BOD disabled) # The following do NOT work... # attiny84at1.upload.using=avrispv2 # attiny84at1.upload.using=Pololu USB AVR Programmer # The following DO work (pick one)... attiny84at1.upload.using=arduino:arduinoisp # attiny84at1.upload.protocol=avrispv2 # attiny84at1.upload.using=pololu attiny84at1.upload.maximum_size=8192 # Default clock (slowly rising power; long delay to clock; 8 MHz internal; divide clock by 8) # Int. RC Osc. 8 MHz; Start-up time PWRDWN/RESET: 6 CK/14 CK + 64 ms; [CKSEL=0010 SUT=10]; default value # Divide clock by 8 internally; [CKDIV8=0] # Brown-out detection disabled; [BODLEVEL=111] # Preserve EEPROM memory through the Chip Erase cycle; [EESAVE=0] attiny84at1.bootloader.low_fuses=0x62 attiny84at1.bootloader.high_fuses=0xD7 attiny84at1.bootloader.extended_fuses=0xFF attiny84at1.bootloader.path=empty attiny84at1.bootloader.file=empty84at1.hex attiny84at1.build.mcu=attiny84 attiny84at1.build.f_cpu=1000000L attiny84at1.build.core=tiny ###########################################################################
-
/root/sketchbook/hardware/attiny/variants/tiny8/pins_arduino.hC
Display More/* pins_arduino.c - pin definitions for the Arduino board Part of Arduino / Wiring Lite Copyright (c) 2005 David A. Mellis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Id: pins_arduino.c 565 2009-03-25 10:50:00Z dmellis $ Modified 28-08-2009 for attiny84 R.Wiersma Modified 09-10-2009 for attiny45 A.Saporetti */ #ifndef Pins_Arduino_h #define Pins_Arduino_h #include <avr/pgmspace.h> // ATMEL ATTINY45 / ARDUINO // // +-\/-+ // Ain0 (D 5) PB5 1| |8 Vcc // Ain3 (D 3) PB3 2| |7 PB2 (D 2) Ain1 // Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1 // GND 4| |5 PB0 (D 0) pwm0 // +----+ static const uint8_t A0 = 6; static const uint8_t A1 = 7; static const uint8_t A2 = 8; static const uint8_t A3 = 9; #define digitalPinToPCICR(p) ( ((p) >= 0 && (p) <= 4) ? (&GIMSK) : ((uint8_t *)0) ) #define digitalPinToPCICRbit(p) ( PCIE ) #define digitalPinToPCMSK(p) ( ((p) <= 4) ? (&PCMSK) : ((uint8_t *)0) ) #define digitalPinToPCMSKbit(p) ( (p) ) #define analogPinToChannel(p) ( (p) < 6 ? (p) : (p) - 6 ) #ifdef ARDUINO_MAIN // these arrays map port names (e.g. port B) to the // appropriate addresses for various functions (e.g. reading // and writing) tiny45 only port B const uint16_t PROGMEM port_to_mode_PGM[] = { NOT_A_PORT, NOT_A_PORT, (uint16_t) &DDRB, }; const uint16_t PROGMEM port_to_output_PGM[] = { NOT_A_PORT, NOT_A_PORT, (uint16_t) &PORTB, }; const uint16_t PROGMEM port_to_input_PGM[] = { NOT_A_PIN, NOT_A_PIN, (uint16_t) &PINB, }; const uint8_t PROGMEM digital_pin_to_port_PGM[] = { PB, /* 0 */ PB, PB, PB, PB, PB, // 5 PB, // A0 PB, PB, PB, // A4 }; const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { _BV(0), /* 0, port B */ _BV(1), _BV(2), _BV(3), /* 3 port B */ _BV(4), _BV(5), _BV(5), _BV(2), _BV(4), _BV(3), }; const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { TIMER0A, /* OC0A */ TIMER0B, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, }; #endif #endif
-
/root/sketchbook/hardware/attiny/variants/tiny14/pins_arduino.hC
Display More/* pins_arduino.c - pin definitions for the Arduino board Part of Arduino / Wiring Lite Copyright (c) 2005 David A. Mellis This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Id: pins_arduino.c 565 2009-03-25 10:50:00Z dmellis $ Modified 28-08-2009 for attiny84 R.Wiersma Modified 09-10-2009 for attiny45 A.Saporetti */ #ifndef Pins_Arduino_h #define Pins_Arduino_h #include <avr/pgmspace.h> // ATMEL ATTINY84 / ARDUINO // // +-\/-+ // VCC 1| |14 GND // (D 10) PB0 2| |13 AREF (D 0) // (D 9) PB1 3| |12 PA1 (D 1) // PB3 4| |11 PA2 (D 2) // PWM INT0 (D 8) PB2 5| |10 PA3 (D 3) // PWM (D 7) PA7 6| |9 PA4 (D 4) // PWM (D 6) PA6 7| |8 PA5 (D 5) PWM // +----+ const static uint8_t A0 = 0; const static uint8_t A1 = 1; const static uint8_t A2 = 2; const static uint8_t A3 = 3; const static uint8_t A4 = 4; const static uint8_t A5 = 5; const static uint8_t A6 = 6; const static uint8_t A7 = 7; #define digitalPinToPCICR(p) ( ((p) >= 0 && (p) <= 10) ? (&GIMSK) : ((uint8_t *)0) ) #define digitalPinToPCICRbit(p) ( ((p) <= 7) ? PCIE0 : PCIE1 ) #define digitalPinToPCMSK(p) ( ((p) <= 7) ? (&PCMSK0) : (((p) <= 10) ? (&PCMSK1) : ((uint8_t *)0)) ) #define digitalPinToPCMSKbit(p) ( ((p) <= 7) ? (p) : (10 - (p)) ) #ifdef ARDUINO_MAIN // these arrays map port names (e.g. port B) to the // appropriate addresses for various functions (e.g. reading // and writing) const uint16_t PROGMEM port_to_mode_PGM[] = { NOT_A_PORT, (uint16_t)&DDRA, (uint16_t)&DDRB, }; const uint16_t PROGMEM port_to_output_PGM[] = { NOT_A_PORT, (uint16_t)&PORTA, (uint16_t)&PORTB, }; const uint16_t PROGMEM port_to_input_PGM[] = { NOT_A_PORT, (uint16_t)&PINA, (uint16_t)&PINB, }; const uint8_t PROGMEM digital_pin_to_port_PGM[] = { PA, /* 0 */ PA, PA, PA, PA, PA, PA, PA, PB, /* 8 */ PB, PB, }; const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = { _BV(0), /* port A */ _BV(1), _BV(2), _BV(3), _BV(4), _BV(5), _BV(6), _BV(7), _BV(2), /* port B */ _BV(1), _BV(0), }; const uint8_t PROGMEM digital_pin_to_timer_PGM[] = { NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, NOT_ON_TIMER, TIMER1B, /* OC1B */ TIMER1A, /* OC1A */ TIMER0B, /* OC0B */ TIMER0A, /* OC0A */ NOT_ON_TIMER, NOT_ON_TIMER, }; #endif #endif
-
/root/sketchbook/hardware/attiny/boards.txt
- Standardmässig öffnet ArduinoIDE ein Sketch unter /usr/share/arduino/ , also am besten einfach die Send.ino und Receive.ino dort hin kopieren.
- Unter LXDE -> ArduinoIDE starten und besagte Dateien öffnen
- In ArduinoIDE auf das Menü Tools -> Board gehen und dort ATtiny84 (internal 8 MHz clock) auswählen
- In ArduinoIDE auf das Menü Tools gehen und dann auf Bootloader installieren (damit wird er auf 8 MHz eingestellt - nur einmal nöitg)
- In ArduinoIDE auf das Menü Datei -> Einstellungen gehen und dort einstellen: Ausführliche Ausgabe anzeigen während: [x] Kompilierung
- Auf den "abgehakt" Haken klicken (Überprüfen)
- ..Leider wird das *.hex File in ein zufällig erstelltes Verzeichnis in /tmp/ abgelegt. Da dies also bei euch anders lautet macht ihr einfach folgendes um den Code auf den ATtiny zu flashen:
dragoner2k hat herausgefunden wie man den Sketch über den RaspberryPI anschließend auch direkt über ArduinoIDE flashen kann:
In der /usr/share/arduino/hardware/arduino/programmers.txt die folgenden Zeilen einfügen:
dann kann man die ATtiny's mit der Direktverdrahtung flashen.
Zum flashen über einen Arduino wie zum Beispiel den UNO unter Windows:
Benötigt wird ArduinoIDE und WinAVR
Vor dem flashen müsst ihr euren ArduinoUNO noch zu nem ISP machen, das geht wie folgt:
- ArduinoIDE starten
- Datei -> Beispiele -> ArduinoISP
- Es öffnet sich ein neues Fenster in dem ihr folgendes macht:
- Tools -> Board -> Arduino Uno
- Tools -> Programmer -> AVR ISP
- Anschliesend auf den "Pfeil nach rechts" klicken (Upload)
Dann zunächst http://arduino-tiny.googlecode…rduino-tiny-0150-0018.zip herunterladen und den darin befindlichen Ordner "tiny" in euren Sketchbook Ordner nach " hardware " entpacken:
Euren "Sketchbook Ordner" könnt ihr wie folgt festlegen:
- ArduinoIDE starten
- Datei -> Einstellungen
- Ganz oben: Sketchbook Speicherort zum Beispiel auf C:\Sketches ändern (Verzeichnis muss existieren)
In eurem Sketchbook Ordner muss es folgende Verzeichnisse geben:
- hardware
- tiny
- libraries
- RFM12B
- JeeLib
- DHT22
Die Libs könnt ihr auf folgenden Links herunterladen:
https://github.com/LowPowerLab/RFM12B/archive/master.zip
https://github.com/jcw/jeelib/archive/master.zip
https://github.com/nethoncho/A…-DHT22/archive/master.zip
Nun müsst ihr leider noch mal in den Ordner " hardware\tiny\avr\ " gehen und die Datei " Prospective Boards.txt " in -> " boards.txt " umbenennen
Wem das zu kompliziert ist kann auch einfach mein Sketchbook verwenden
Zum Kompilieren und Hochladen des Sketches geht ihr wie folgt vor.
Einmalig:
- In ArduinoIDE auf das Menü Tools -> Board gehen und dort ATtiny84 (internal 8 MHz clock) auswählen
- In ArduinoIDE auf das Menü Tools -> Programmer gehen und dort Arduino as ISP auswählen
- In ArduinoIDE auf das Menü Datei -> Einstellungen gehen und dort einstellen: Ausführliche Ausgabe anzeigen während: [x] Kompilierung
- In ArduinoIDE auf das Menü Tools gehen und dann auf Bootloader installieren (damit wird er auf 8 MHz eingestellt - nur einmal nötig)
Anschliesend:
- Entweder auf den "abgehakt" Haken klicken (Überprüfen) - damit wird der Code kompiliert
- Oder zum kombinierten kompilieren und anschliesenden Hochladen auf den "Pfeil nach rechts" klicken
Anschlussplan zum Flashen des ATtiny84 über einen ArduinoUNO:
- Arduino 5V an ATtiny84 Pin 1 (VCC +)
- Arduino GND an ATTiny84 Pin 14 (GND -)
- Arduino Pin 10 an ATtiny84 Pin 4 (Reset)
- Arduino Pin 11 an ATTiny84 Pin 7 (Pin 6, PWM, Analog Input 7)
- Arduino Pin 12 an ATTiny84 Pin 8 (Pin 5, Analog Input 5, PWM, MISO)
- Arduino Pin 13 an ATTiny84 Pin 9 (Pin 4, Analog Input 4, SCK)
Wer mit der RFM12B lib einen Sketch kompilieren möchte muss die RFM12B.h anpassen und zwar so:
Zeile 202:
void SendStart(uint8_t toNodeId, const void* sendBuf, uint8_t sendLen, bool requestACK=false, bool sendACK=false, uint8_t waitMode=SLEEP_MODE_STANDBY);
Ändern in:
void SendStart(uint8_t toNodeId, const void* sendBuf, uint8_t sendLen, bool requestACK=false, bool sendACK=false, uint8_t waitMode=SLEEP_MODE_PWR_DOWN);
Zeile 204:
void Send(uint8_t toNodeId, const void* sendBuf, uint8_t sendLen, bool requestACK = false, uint8_t waitMode=SLEEP_MODE_STANDBY);
Ändern in:
void Send(uint8_t toNodeId, const void* sendBuf, uint8_t sendLen, bool requestACK = false, uint8_t waitMode=SLEEP_MODE_PWR_DOWN);
Offensichtlich ist das WinAVR (von 2008) welches bei ArduinoIDE dabei ist, fehlerhaft
Die Lösung ist relativ einfach:
- Ladet euch die aktuelle WinAVR-Suite (aktuell von 2010) von SourceForge herunter, installiert sie z.B. nach C:\WinAVR
- Benennt den Ordner “avr” im Verzeichnis “C:\Program Files (x86)\Arduino\hardware\tools” in “avr.old“ um
- Erstellt das Verzeichnis “avr” neu und kopiert dorthin alle Dateien und Ordner unterhalb von C:\WinAVR\
- Aus dem alten und umbenannten Ordner “avr.old“ muss nun noch das Verzeichnis “etc“ ins neue kopiert werden (genauer gesagt die avrdude.conf)
Danach funktioniert auch das kompilieren der Sketches wieder!
UART:
Die UART-Schnittstelle wird bei Raspbian wheezy standardmässig als serielle Konsole genutz. Damit die UART-Schnittstelle genutzt werden kann, ist diese Funktion zu deaktivieren...
Dazu in der Datei /boot/cmdline.txt folgende Parameter löschen:
Anschliessend sollte die Zeile wie folgt aussehen:
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
Ausserdem muss in der Datei /etc/inittab folgende Zeile durch voranstellein eines # auskommentiert werden:
Anschliesend rebooten und dann kannst du UART verwenden
quelle: https://asciich.ch/wordpress/u…f-dem-raspberrypi-nutzen/
Sketches für Sender und Receiver, sowie die benötigten Scripts auf dem RaspberryPI zum speichern und auswerten der Daten
Receiver_PI.ino:
// RFM12B Receiver for RaspberryPI
//
// Basiert zum Teil auf der Arbeit von Nathan Chantrell
//
// modified by meigrafd @ 16.12.2013 - for UART on RaspberryPI
//------------------------------------------------------------------------------
#include <RFM12B.h>
#include <avr/sleep.h>
#include <SoftwareSerial.h>
//------------------------------------------------------------------------------
// You will need to initialize the radio by telling it what ID it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. You can change it by calling .SetCS(pin) where pin can be {8,9,10}
#define NODEID 22 //network ID used for this unit
#define NETWORKID 210 //the network ID we are on
#define ACK_TIME 2000 // # of ms to wait for an ack
#define SERIAL_BAUD 9600
//------------------------------------------------------------------------------
// PIN-Konfiguration
//------------------------------------------------------------------------------
// UART pins
#define rxPin 7 // D7, PA3
#define txPin 3 // pin an den der 433 Mhz Sender angeschlossen ist (D3, PA7)
// LED pin
#define LEDpin 8 // D8, PA2 - set to 0 to disable LED
/*
+-\/-+
VCC 1| |14 GND
(D0) PB0 2| |13 AREF (D10)
(D1) PB1 3| |12 PA1 (D9)
RESET 4| |11 PA2 (D8)
INT0 PWM (D2) PB2 5| |10 PA3 (D7)
PWM (D3) PA7 6| |9 PA4 (D6)
PWM (D4) PA6 7| |8 PA5 (D5) PWM
+----+
*/
//encryption is OPTIONAL
//to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start en
// - to stop encrypting call .Encrypt(NULL)
//#define KEY "ABCDABCDABCDABCD"
// Initialise UART
SoftwareSerial mySerial(rxPin, txPin);
// Need an instance of the Radio Module
RFM12B radio;
//##############################################################################
static void activityLED (byte mode) {
pinMode(LEDpin, OUTPUT);
digitalWrite(LEDpin, mode);
}
// blink led
static void blink (byte pin, byte n = 3) {
pinMode(pin, OUTPUT);
for (byte i = 0; i < 2 * n; ++i) {
delay(100);
digitalWrite(pin, !digitalRead(pin));
}
}
// init Setup
void setup() {
pinMode(rxPin, INPUT);
pinMode(txPin, OUTPUT);
mySerial.begin(SERIAL_BAUD);
radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
#ifdef KEY
radio.Encrypt((byte*)KEY); //comment this out to disable encryption
#endif
if (LEDpin) {
activityLED(1); // LED on
delay(1000);
activityLED(0); // LED off
}
}
// Loop
void loop() {
if (radio.ReceiveComplete()) {
if (radio.CRCPass()) {
//node ID of TX, extracted from RF datapacket. Not transmitted as part of structure
mySerial.print(radio.GetSender(), DEC);
mySerial.print(" ");
int i;
for (byte i = 0; i < *radio.DataLen; i++) //can also use radio.GetDataLen() if you don't like pointers
mySerial.print((char) radio.Data[i]);
if (LEDpin) {
blink(LEDpin, 2);
}
if (radio.ACKRequested()) {
radio.SendACK();
}
} else {
mySerial.print("BAD-CRC");
if (LEDpin) {
activityLED(1); // LED on
delay(1000);
activityLED(0); // LED off
}
}
mySerial.println();
}
}
Display More
Send_DHT22.ino:
// RFM12B Sender for DHT22 Sensor
//
// Basiert zum Teil auf der Arbeit von Nathan Chantrell
//
// modified by meigrafd @ 16.12.2013
//------------------------------------------------------------------------------
#include <RFM12B.h>
#include <avr/sleep.h>
#include <DHT22.h> // https://github.com/nathanchantrell/Arduino-DHT22
//------------------------------------------------------------------------------
// You will need to initialize the radio by telling it what ID it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. You can change it by calling .SetCS(pin) where pin can be {8,9,10}
#define NODEID 20 //network ID used for this unit
#define NETWORKID 210 //the network ID we are on
#define GATEWAYID 22 //the node ID we're sending to
#define ACK_TIME 2000 // # of ms to wait for an ack
#define SENDDELAY 300000 // wait this many ms between sending packets. 300000ms = 5min
#define requestACK false // request ACK? (true/false)
//------------------------------------------------------------------------------
// PIN-Konfiguration
//------------------------------------------------------------------------------
// SENSOR pins
#define DHT22_PIN 10 // DHT sensor is connected on D10 (ATtiny pin 13)
#define DHT22_POWER 9 // DHT Power pin is connected on D9 (ATtiny pin 12)
// LED pin
#define LEDpin 8 // D8, PA2 - set to 0 to disable LED
//------------------------------------------------------------------------------
/*
+-\/-+
VCC 1| |14 GND
(D0) PB0 2| |13 AREF (D10)
(D1) PB1 3| |12 PA1 (D9)
RESET 4| |11 PA2 (D8)
INT0 PWM (D2) PB2 5| |10 PA3 (D7)
PWM (D3) PA7 6| |9 PA4 (D6)
PWM (D4) PA6 7| |8 PA5 (D5) PWM
+----+
*/
//encryption is OPTIONAL
//to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
//#define KEY "ABCDABCDABCDABCD"
// Need an instance of the Radio Module
RFM12B radio;
// Setup the DHT
DHT22 myDHT22(DHT22_PIN);
// Variablen für Temperatur/Luftfeuchtigkeit
long temp; long humi;
// Temperatur-String zum Versand per 433 Mhz
char msg[26];
//##############################################################################
static void activityLed (byte state, byte time = 0) {
if (LEDpin) {
pinMode(LEDpin, OUTPUT);
if (time == 0) {
digitalWrite(LEDpin, state);
} else {
digitalWrite(LEDpin, state);
delay(time);
digitalWrite(LEDpin, !state);
}
}
}
// blink led
static void blink (byte pin, byte n = 3) {
if (LEDpin) {
pinMode(pin, OUTPUT);
for (byte i = 0; i < 2 * n; ++i) {
delay(100);
digitalWrite(pin, !digitalRead(pin));
}
}
}
// sec since start
static unsigned long now() {
// FIXME 49-day overflow
return millis() / 1000;
}
//--------------------------------------------------------------------------------------------------
// Read current supply voltage (in mV)
//--------------------------------------------------------------------------------------------------
long readVcc() {
bitClear(PRR, PRADC);
ADCSRA |= bit(ADEN); // Enable the ADC
long result;
// Read 1.1V reference against Vcc
#if defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate Vcc in mV
ADCSRA &= ~ bit(ADEN);
bitSet(PRR, PRADC); // Disable the ADC to save power
return result;
}
// init Setup
void setup() {
pinMode(DHT22_POWER, OUTPUT); // set power pin for Sensor to output
radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
#ifdef KEY
radio.Encrypt((byte*)KEY); //comment this out to disable encryption
#endif
// configure RFM12B
radio.Control(0xC040); // Adjust low battery voltage to 2.2V
radio.Sleep(); //sleep right away to save power
PRR = bit(PRTIM1); // only keep timer 0 going
analogReference(INTERNAL); // Set the aref to the internal 1.1V reference
ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
activityLed(1,1000); // LED on for 1000ms
}
// Loop
void loop() {
activityLed(1); // LED on
pinMode(DHT22_POWER, OUTPUT); // set power pin for Sensor to output
digitalWrite(DHT22_POWER, HIGH); // turn Sensor on
DHT22_ERROR_t errorCode;
delay(2500); // Kurzer Delay zur Initialisierung (DHT22 benoetigt mindestens 2 Sekunden fuer Aufwaermphase nach dem Power-On)
errorCode = myDHT22.readData(); // read data from sensor
activityLed(0); // LED off
if (errorCode == DHT_ERROR_NONE) { // data is good
int temp = (myDHT22.getTemperatureC()*100); // Get temperature reading and convert to integer, reversed at receiving end
int humi = (myDHT22.getHumidity()*100); // Get humidity reading and convert to integer, reversed at receiving end
int vcc = readVcc(); // Get supply voltage
// msg-Variable mit Daten zum Versand fuellen, die spaeter an das WebScript uebergeben werden
//snprintf(msg, 26, "v=%d&t=%d&h=%d", vcc,temp,humi);
strcpy(msg,"v=");
itoa(vcc,&msg[strlen(msg)],10);
strcat(msg,"&t=");
itoa(temp,&msg[strlen(msg)],10);
strcat(msg,"&h=");
itoa(humi,&msg[strlen(msg)],10);
radio.Wakeup();
radio.Send(GATEWAYID, (uint8_t *)msg, strlen(msg), requestACK);
radio.SendWait(2); //wait for RF to finish sending (2=standby mode)
radio.Sleep();
if (LEDpin) {
blink(LEDpin, 2); // blink LED
}
}
digitalWrite(DHT22_POWER, LOW); // turn Sensor off to save power
pinMode(DHT22_POWER, INPUT); // set power pin for Sensor to input before sleeping, saves power
delay(SENDDELAY);
}
Display More
Send_TMP36.ino:
// RFM12B Sender for TMP36 Sensor
//
// Basiert zum Teil auf der Arbeit von Nathan Chantrell
//
// modified by meigrafd @ 16.12.2013
//------------------------------------------------------------------------------
#include <RFM12B.h>
#include <avr/sleep.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 3);
//------------------------------------------------------------------------------
// You will need to initialize the radio by telling it what ID it has and what network it's on
// The NodeID takes values from 1-127, 0 is reserved for sending broadcast messages (send to all nodes)
// The Network ID takes values from 0-255
// By default the SPI-SS line used is D10 on Atmega328. You can change it by calling .SetCS(pin) where pin can be {8,9,10}
#define NODEID 19 // network ID used for this unit
#define NETWORKID 210 // the network ID we are on
#define GATEWAYID 22 // the node ID we're sending to
#define ACK_TIME 2000 // # of ms to wait for an ack
#define SENDDELAY 300000 // wait this many ms between sending packets. 300000ms = 5min
#define requestACK true // request ACK? (true/false)
//------------------------------------------------------------------------------
// PIN-Konfiguration
//------------------------------------------------------------------------------
// SENSOR pins
#define tempPin 10 // Sensor Vout connected to D10 (ATtiny pin 13)
#define tempPower 9 // Sensor Power connected to D9 (ATtiny pin 12)
// LED pin
#define LEDpin 8 // LED power connected to D8 (ATtiny pin 11)
/*
+-\/-+
VCC 1| |14 GND
(D0) PB0 2| |13 AREF (D10)
(D1) PB1 3| |12 PA1 (D9)
RESET 4| |11 PA2 (D8)
INT0 PWM (D2) PB2 5| |10 PA3 (D7)
PWM (D3) PA7 6| |9 PA4 (D6)
PWM (D4) PA6 7| |8 PA5 (D5) PWM
+----+
*/
//encryption is OPTIONAL
//to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
//#define KEY "ABCDABCDABCDABCD"
// Need an instance of the Radio Module
RFM12B radio;
// Analogue reading from the sensor
int tempReading;
// String zum Versand
char msg[26];
//##############################################################################
static void activityLed (byte state) {
pinMode(LEDpin, OUTPUT);
digitalWrite(LEDpin, state);
}
// blink led
static void blink (byte pin, byte n = 3) {
pinMode(pin, OUTPUT);
for (byte i = 0; i < 2 * n; ++i) {
delay(100);
digitalWrite(pin, !digitalRead(pin));
}
}
//--------------------------------------------------------------------------------------------------
// Read current supply voltage (in mV)
//--------------------------------------------------------------------------------------------------
long readVcc() {
bitClear(PRR, PRADC);
ADCSRA |= bit(ADEN); // Enable the ADC
long result;
// Read 1.1V reference against Vcc
#if defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate Vcc in mV
ADCSRA &= ~ bit(ADEN);
bitSet(PRR, PRADC); // Disable the ADC to save power
return result;
}
// init Setup
void setup() {
pinMode(tempPower, OUTPUT);
pinMode(tempPin, INPUT);
radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
#ifdef KEY
radio.Encrypt((byte*)KEY); //comment this out to disable encryption
#endif
analogReference(INTERNAL); // Set the aref to the internal 1.1V reference
// configure RFM12B
radio.Control(0xC040); // Adjust low battery voltage to 2.2V
radio.Sleep(); //sleep right away to save power
if (LEDpin) {
activityLed(1); // LED on
delay(1000);
activityLed(0); // LED off
}
mySerial.begin(9600);
}
// Loop
void loop() {
pinMode(tempPower, OUTPUT);
digitalWrite(tempPower, HIGH); // turn Sensor on
delay(500); // Kurzer Delay zur Initialisierung (DHT22 benoetigt mindestens 2 Sekunden fuer Aufwaermphase nach dem Power-On)
bitClear(PRR, PRADC); // power up the ADC
ADCSRA |= bit(ADEN); // Enable the ADC
analogRead(tempPin); // throw away the first reading
ADCSRA &= ~ bit(ADEN); // disable the ADC
bitSet(PRR, PRADC); // power down the ADC
for(int i = 0; i < 10 ; i++) { // take 10 more readings
tempReading += analogRead(tempPin); // accumulate readings
}
tempReading = tempReading / 10 ; // calculate the average
double voltage = tempReading * (1100/1024); // Convert to mV (assume internal reference is accurate)
double temperatureC = (voltage - 500) / 10; // Convert to temperature in degrees C.
int temp = temperatureC * 100; // Convert temperature to an integer, reversed at receiving end
int supplyV = readVcc(); // Get supply voltage
// msg-Variable mit Daten zum Versand füllen, die später an das WebScript übergeben werden
snprintf(msg, 26, "v=%d&t=%d", supplyV,temp) ;
//mySerial.print(msg);
radio.Wakeup();
radio.Send(GATEWAYID, (uint8_t *)msg, strlen(msg), requestACK);
radio.SendWait(2); //wait for RF to finish sending (2=standby mode)
radio.Sleep();
digitalWrite(tempPower, LOW); // turn Sensor off
pinMode(tempPower, INPUT); // set power pin for Sensor to input before sleeping, saves power
if (LEDpin) {
blink(LEDpin, 2); // LED on
}
delay(SENDDELAY);
}
Display More
Send_DS18B20.ino
//--------------------------------------------------------------------------------------
// TempTX-tiny ATtiny84 Based Wireless Temperature Sensor Node
// By Nathan Chantrell http://nathan.chantrell.net
// Updated by Martin Harizanov (harizanov.com) to work with DS18B20
// To use with DS18B20 instead of TMP36, a 4K7 resistor is needed between the Digital 9 and Digital 10 of the ATTiny (Vdd and DQ)
// To get this to compile follow carefully the discussion here: http://arduino.cc/forum/index.php?topic=91491.0
// GNU GPL V3
//--------------------------------------------------------------------------------------
// modified by meigrafd @ 26.12.2013
//------------------------------------------------------------------------------
//#include <JeeLib.h> // https://github.com/jcw/jeelib
#include "pins_arduino.h"
#include <RFM12B.h>
#include <avr/sleep.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//------------------------------------------------------------------------------
#define NODEID 1 // RF12 node ID in the range 1-30
#define NETWORKID 210 // RF12 Network group
#define FREQ RF12_433MHZ // Frequency of RFM12B module
#define GATEWAYID 22 // the node ID we're sending to
#define ACK_TIME 2000 // Number of milliseconds to wait for an ack
#define SENDDELAY 300000 // wait this many ms between sending packets
#define requestACK true // request ACK? (true/false)
//------------------------------------------------------------------------------
// PIN-Konfiguration
//------------------------------------------------------------------------------
// SENSOR pins
#define ONE_WIRE_BUS 10 // DS18B20 Temperature sensor is connected on D10/ATtiny pin 13
#define ONE_WIRE_POWER 9 // DS18B20 Power pin is connected on D9/ATtiny pin 12
// LED pin
#define LEDpin 8 // D8, PA2 (ATtiny pin 11) - set to 0 to disable LED
//------------------------------------------------------------------------------
/*
+-\/-+
VCC 1| |14 GND
(D0) PB0 2| |13 AREF (D10)
(D1) PB1 3| |12 PA1 (D9)
RESET 4| |11 PA2 (D8)
INT0 PWM (D2) PB2 5| |10 PA3 (D7)
PWM (D3) PA7 6| |9 PA4 (D6)
PWM (D4) PA6 7| |8 PA5 (D5) PWM
+----+
*/
//encryption is OPTIONAL
//to enable encryption you will need to:
// - provide a 16-byte encryption KEY (same on all nodes that talk encrypted)
// - to call .Encrypt(KEY) to start encrypting
// - to stop encrypting call .Encrypt(NULL)
//#define KEY "ABCDABCDABCDABCD"
//------------------------------------------------------------------------------
// Need an instance of the Radio Module
RFM12B radio;
// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Temperatur-String zum Versand per 433 Mhz
char msg[26];
//########################################################################################################################
static void activityLed (byte state, byte time = 0) {
if (LEDpin) {
pinMode(LEDpin, OUTPUT);
if (time == 0) {
digitalWrite(LEDpin, state);
} else {
digitalWrite(LEDpin, state);
delay(time);
digitalWrite(LEDpin, !state);
}
}
}
// blink led
static void blink (byte pin, byte n = 3) {
if (LEDpin) {
pinMode(pin, OUTPUT);
for (byte i = 0; i < 2 * n; ++i) {
delay(100);
digitalWrite(pin, !digitalRead(pin));
}
}
}
//--------------------------------------------------------------------------------------------------
// Read current supply voltage
//--------------------------------------------------------------------------------------------------
long readVcc() {
//bitClear(PRR, PRADC);
//ADCSRA |= bit(ADEN); // Enable the ADC
long result;
// Read 1.1V reference against Vcc
#if defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate Vcc in mV
//ADCSRA &= ~ bit(ADEN);
//bitSet(PRR, PRADC); // Disable the ADC to save power
return result;
}
void setup() {
radio.Initialize(NODEID,FREQ,NETWORKID); // Initialize RFM12 with settings defined above
#ifdef KEY
radio.Encrypt((byte*)KEY);
#endif
radio.Control(0xC040); // Adjust low battery voltage to 2.2V
radio.Sleep(); // Put the RFM12 to sleep
PRR = bit(PRTIM1); // only keep timer 0 going
ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
delay(100);
// Start up the library
sensors.begin();
}
void loop() {
pinMode(ONE_WIRE_POWER, OUTPUT); // set power pin for DS18B20 to output
digitalWrite(ONE_WIRE_POWER, HIGH); // turn DS18B20 sensor on
delay(50); // Allow 50ms for the sensor to be ready
sensors.requestTemperatures(); // Send the command to get temperatures
int temp = sensors.getTempCByIndex(0)*100; // read sensor 1
//String temp2=(sensors.getTempCByIndex(1)*100); // read second sensor.. you may have multiple and count them upon startup but I only need one
int supplyV = readVcc(); // Get supply voltage
digitalWrite(ONE_WIRE_POWER, LOW); // turn Sensor off to save power
pinMode(ONE_WIRE_POWER, INPUT); // set power pin for Sensor to input before sleeping, saves power
// msg-Variable mit Daten zum Versand fuellen, die spaeter an das WebScript uebergeben werden
strcpy(msg,"v=");
itoa(supplyV,&msg[strlen(msg)],10);
strcat(msg,"&t=");
itoa(temp,&msg[strlen(msg)],10);
// Send data via RF
radio.Wakeup();
radio.Send(GATEWAYID, (uint8_t *)msg, strlen(msg), requestACK);
//radio.Send(GATEWAYID, &msg, sizeof(msg), requestACK);
radio.SendWait(2); //wait for RF to finish sending (2=standby mode)
radio.Sleep();
if (LEDpin) {
blink(LEDpin, 2); // blink LED
}
delay(SENDDELAY);
}
Display More
Send_ReedSwitch.ino
//----------------------------------------------------------------------------------------------------------------------
// TinyTX - An ATtiny84 and RFM12B Wireless Sensor Node
// By Nathan Chantrell. For hardware design see http://nathan.chantrell.net/tinytx
//
// Detect a normally closed reed switch opening and closing with pin change interrupt to wake from sleep.
//
// Licenced under the Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) licence:
// http://creativecommons.org/licenses/by-sa/3.0/
//
// Requires Arduino IDE with arduino-tiny core: http://code.google.com/p/arduino-tiny/
//----------------------------------------------------------------------------------------------------------------------
// modified by meigrafd @ 05.01.2014
//------------------------------------------------------------------------------
#include <RFM12B.h>
#include <avr/sleep.h>
#include <PinChangeInterrupt.h> // http://code.google.com/p/arduino-tiny/downloads/list
#define NODEID 20 // network ID used for this unit
#define NETWORKID 210 // the network ID we are on
#define GATEWAYID 22 // the node ID we're sending to
#define FREQ RF12_433MHZ // Frequency of RFM12B module
#define ACK_TIME 2000 // # of ms to wait for an ack
#define requestACK false // request ACK? (true/false)
#define SENDDELAY 30000 // wait this many ms between sending packets. 30000ms = 30sek
//------------------------------------------------------------------------------
// PIN-Konfiguration
//------------------------------------------------------------------------------
#define SW_PIN 10 // Reed switch connected from ground to this pin (D10/ATtiny pin 13)
// LED pin
#define LEDpin 0 // D8, PA2 (ATtiny pin 11) - set to 0 to disable LED
//------------------------------------------------------------------------------
/*
+-\/-+
VCC 1| |14 GND
(D0) PB0 2| |13 AREF (D10)
(D1) PB1 3| |12 PA1 (D9)
RESET 4| |11 PA2 (D8)
INT0 PWM (D2) PB2 5| |10 PA3 (D7)
PWM (D3) PA7 6| |9 PA4 (D6)
PWM (D4) PA6 7| |8 PA5 (D5) PWM
+----+
*/
//########################################################################################################################
//Data Structure to be sent
//########################################################################################################################
// Need an instance of the Radio Module
RFM12B radio;
// String zum Versand per 433 Mhz
char msg[26];
// Reed switchState
int switchState;
//########################################################################################################################
static void activityLed (byte state, byte time = 0) {
if (LEDpin) {
pinMode(LEDpin, OUTPUT);
if (time == 0) {
digitalWrite(LEDpin, state);
} else {
digitalWrite(LEDpin, state);
delay(time);
digitalWrite(LEDpin, !state);
}
}
}
// blink led
static void blink (byte pin, byte n = 3) {
if (LEDpin) {
pinMode(pin, OUTPUT);
for (byte i = 0; i < 2 * n; ++i) {
delay(100);
digitalWrite(pin, !digitalRead(pin));
}
}
}
//--------------------------------------------------------------------------------------------------
// Read current supply voltage (in mV)
//--------------------------------------------------------------------------------------------------
long readVcc() {
bitClear(PRR, PRADC);
ADCSRA |= bit(ADEN); // Enable the ADC
long result;
// Read 1.1V reference against Vcc
#if defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0); // For ATtiny84
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); // For ATmega328
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = 1126400L / result; // Back-calculate Vcc in mV
ADCSRA &= ~ bit(ADEN);
bitSet(PRR, PRADC); // Disable the ADC to save power
return result;
}
// init Setup
void setup() {
radio.Initialize(NODEID,FREQ,NETWORKID); // Initialize RFM12 with settings defined above
radio.Control(0xC040); // Adjust low battery voltage to 2.2V
radio.Sleep(); // Put the RFM12 to sleep
pinMode(SW_PIN, INPUT); //set the pin to input
digitalWrite(SW_PIN, HIGH); //use the internal pullup resistor
attachPcInterrupt(SW_PIN,wakeUp,FALLING); // attach a PinChange Interrupt on the falling edge
analogReference(INTERNAL); // Set the aref to the internal 1.1V reference
PRR = bit(PRTIM1); // only keep timer 0 going
ADCSRA &= ~ bit(ADEN); bitSet(PRR, PRADC); // Disable the ADC to save power
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
sleep_mode(); // Sleep now
if (LEDpin) {
activityLed(1,1000); // LED on
}
}
void wakeUp(){}
// Loop
void loop() {
int State = digitalRead(SW_PIN); // Read the state of the reed switch
if (State == LOW) { // Door/window is open
switchState = 1; // 1 indicates open
} else { // Door/window is closed
switchState = 0; // 0 indicates closed
}
if (switchState == 1) {
int supplyV = readVcc(); // Get supply voltage
// msg-Variable mit Daten zum Versand fuellen, die spaeter an das WebScript uebergeben werden
strcpy(msg,"v=");
itoa(supplyV,&msg[strlen(msg)],10);
strcat(msg,"&r=");
itoa(switchState,&msg[strlen(msg)],10);
// Send data via RF
radio.Wakeup();
radio.Send(GATEWAYID, (uint8_t *)msg, strlen(msg), requestACK);
//radio.Send(GATEWAYID, &msg, sizeof(msg), requestACK);
radio.SendWait(2); //wait for RF to finish sending (2=standby mode)
radio.Sleep();
if (LEDpin) {
blink(LEDpin, 2); // blink LED
}
}
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode
sleep_mode(); // Sleep now
delay(SENDDELAY);
}
Display More
Auf dem RaspberryPI muss dann noch folgendes eingerichtet werden:
Vorraussetzung für nachfolgendes ist:
apt-get update
apt-get install apache2 php5 php5-gd php5-sqlite
apt-get install libdevice-serialport-perl libwww-mechanize-perl libproc-daemon-perl
Das Perl Script welches die Daten vom UART entgegen nimmt und an ein PHP Script weiterreicht:
Sensor.pl
#!/usr/bin/perl -w
# Reads data from serial port and posts to PHP
# Run apt-get install libdevice-serialport-perl
# if you ger "Can't locate device/SerialPort.pm in @INC (@INC includes ..."
# use lib '/usr/lib/perl5/Device'
# sudo apt-get install libwww-mechanize-perl
#To install Proc:Daemon
#perl -MCPAN -e 'install Proc::Daemon' OR sudo apt-get install libproc-daemon-perl
#### CONFIG - START
# Secret Key
my $KEY = '23338d373027ce83b1f81b9e9563b629';
# if not using rrd, set url to add.php
my $url = "http://127.0.0.1/Sensor/add.php?key=". $KEY ."&node=";
# set UART baudrate
my $baudrate = 9600;
my $PORT = "/dev/ttyAMA0";
#### CONFIG - END
# Declare the subroutines
sub trim($);
BEGIN {
push @INC,"/usr/lib/perl5/";
}
use strict;
use Device::SerialPort qw( :PARAM :STAT 0.07 );
use WWW::Mechanize;
use Time::localtime;
use Scalar::Util 'looks_like_number';
use Proc::Daemon;
print "Serial to PHP gateway for RaspberryPi with RFM12B\r\n";
my $ob = Device::SerialPort->new($PORT);
$ob->baudrate($baudrate);
$ob->parity("none");
$ob->databits(8);
$ob->stopbits(1);
#$ob->handshake("xoff");
$ob->write_settings;
open(SERIAL, "+>$PORT");
my $continue = 1;
$SIG{TERM} = sub { $continue = 0 };
while ($continue) {
my $line = trim(<SERIAL>);
print $line; print "\r\n";
my @values = split(' ', $line);
if(looks_like_number($values[0]) && $values[0] >=1) {
post2php($values[0],$values[1]);
sleep(2);
}
}
sub post2php {
my $ua = WWW::Mechanize->new();
my $URL = $url . $_[0] ."&" . $_[1];
#my $url = "http://127.0.0.1/Sensor/add.php?key=23338d373027ce83b1f81b9e9563b629&node=" . $_[0] ."&" . $_[1];
#print $url; print "\r\n";
my $response = $ua->get($URL);
if ($response->is_success) {
#print "Success!\n";
my $c = $ua->content;
print ("$c");
} else {
print "Failed to open url!";
#die $response->status_line;
}
}
# Perl trim function to remove whitespace from the start and end of the string
sub trim($) {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
#
Display More
Dann muss ein Verzeichnis im apache2 Webroot sowie dort ein paar PHP Script angelegt werden:
Hier die erwähnten PHP Scripts: (v0.3: add.php , index.php , functions.php , config.php )
Sensor_php_v0.3.zip
Ich arbeite aber bereits an v0.5 mit Graphen usw
-> Hier findet ihr v0.5: https://www.forum-raspberrypi.…sensor?pid=54921#pid54921
Anschliesend sicherstellen das der apache2 Benutzer in den Verzeichnissen auch schreiben darf:
Dann das Sensor.pl ausführbar machen und anschließend ausführen:
Sender und Empfänger Module einschalten und anschliesend den RaspberryPI WebServer ansurfen:
Dann sieht das in etwa so aus:
Die Temperature Werte sind bei mir aber noch falsch.. Und so super toll sieht die Tabelle vielleicht auch noch nicht aus - aber es funktioniert soweit zumindest schon mal
Damit die Sensor.pl im Hintergrund weiter läuft muss noch ein Programm installiert werden:
Anschliesend würdet ihr das Script dann wie folgt starten können:
Also zum Beispiel: screen -dmS sensor /root/Sensor.pl
Desweiteren ist es ratsam ein Watchdog einzurichten, der jede Minute überprüft ob das Sensor.pl Script noch läuft und falls nicht wird das Script neu gestartet:
nano watchdog_Sensor.sh && chmod +x watchdog_Sensor.sh
#!/bin/bash
# TinyTX Sensor.pl watchdog
#
### CONFIG - START
SCRIPT=/root/Sensor.pl
### CONFIG - END
#SCRIPT gestartet ?
PID="$(pgrep -x $(basename $SCRIPT))"
if [[ ! -z "$PID" ]] ; then
echo "$(date +"%Y-%m-%d %H:%M") Watchdog - $SCRIPT laeuft"
else
screen -dmS sensor $SCRIPT
echo "$(date +"%Y-%m-%d %H:%M") Watchdog - $SCRIPT wurde neu gestartet"
fi
exit 0
Display More
Dann den watchdog in die Crontab eintragen. Wer anstatt vi lieber nano benutzen möchte gibt ein mal vorher export EDITOR=nano ein und ruft anschliesend den Befehl zur bearbeiten der Crontab auf:
Der Eintrag sähe dann zum Beispiel so aus:
Extra Display:
Als Touchscreen Display benutze ich das 2,8" wie es > hier < aufgelistet wurde. Kostet zZt ca. 10,77€ über eBay inkl. VSK
Dabei handelt es sich um das HY28B Display wie es auch > hier < aufgeführt ist, also ein 8-bit SPI was allerdings ein Rastermaß von 2mm hat! Man kriegt dort also nicht ohne weiteres normale Steckbrett-Kabel drauf gesteckt da dafür der Abstand zwischen den Pins zu knapp ist - aber auch hierfür gibt es eine einfache Lösung: https://forum-raspberrypi.de/f…-54mm/?pid=65710#pid65710
Die Installation bzw Einrichtung habe ich > hier < beschrieben
Das Script fürs Touchscreen Display findet ihr > hier <
Die Installation für ein Display ohne Touch, wie ich für das zuvor erwähnte Tiny.py Script genutzt habe, hab ich > hier < beschrieben (2,2" 8-bit SPI für ca. 4€ inkl. VSK)
Links:
Bezüglich dem RFM12B Module von Seegel-Systeme:
https://www.forum-raspberrypi.…sensor?pid=92650#pid92650
https://www.forum-raspberrypi.…sensor?pid=91356#pid91356
https://www.forum-raspberrypi.…sensor?pid=92915#pid92915
History:
- Send_ReedSwitch.ino hinzugefügt
- Display-Beschreibung hinzugefügt