habe Probleme mit dem Betrieb eines DS18S20 - Temperatursensor an einem ATtiny84, programmiert mittels eines Arduino Unos.
Am Arduino mit der gleichen physikalischen Schaltung und dem identisches Softwarecode, bekomme ich realistische Temperaturen. Beim ATtiny hingegen, wandere ich auf einen starren Minuswert.
Hier der Sketch:
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire ds(2);
DeviceAddress sensor = { 0x10, 0x92, 0x43, 0x90, 0x2, 0x8, 0x0, 0x5B };
void setup()
{
pinMode(1, OUTPUT);
Serial.begin(9600);
}
void loop()
{
float temp = getTemperature(sensor);
Serial.println(temp);
delay(200);
if(temp < 10)
{
digitalWrite(1, HIGH);
}
}
void writeTimeToScratchpad(byte* address)
{
//reset the bus
ds.reset();
//select our sensor
ds.select(address);
//CONVERT T function call (44h) which puts the temperature into the scratchpad
ds.write(0x44,1);
//sleep a second for the write to take place
delay(1000);
}
void readTimeFromScratchpad(byte* address, byte* data)
{
//reset the bus
ds.reset();
//select our sensor
ds.select(address);
//read the scratchpad (BEh)
ds.write(0xBE);
for (byte i=0;i<9;i++){
data[i] = ds.read();
}
}
float getTemperature(byte* address)
{
int tr;
byte data[12];
writeTimeToScratchpad(address);
readTimeFromScratchpad(address,data);
//put in temp all the 8 bits of LSB (least significant byte)
tr = data[0];
//check for negative temperature
if (data[1] > 0x80)
{
tr = !tr + 1; //two's complement adjustment
tr = tr * -1; //flip value negative.
}
//COUNT PER Celsius degree (10h)
int cpc = data[7];
//COUNT REMAIN (0Ch)
int cr = data[6];
//drop bit 0
tr = tr >> 1;
return tr - (float)0.25 + (cpc - cr)/(float)cpc;
}
Der DS18S20 hängt im Code an Pin 2, welcher bei mir physikalisch an Pin 11 bzw. PA2 hängt.
Bist Du sicher, daß die 2 Bibliotheken auf dem ATtiny84 funktionieren?
Der hat ja eine Andere HW-Ausstattung als ein ATmega (Timer, Flash, RAM)
Grüße Uwe
Gibt es eine andere Möglichkeit / Libraries wie ich den DS18S20 am ATtiny84 richtig zum laufen bekomme?
Ich bin jetzt nicht festgesetzt auf meine Lösung.
Ist für ein RFM12-Funkmodul, abgeändert dürfte der in etwa so aussehen (serielle Ausgabe für den ATtiny84 rauskommentieren):
#include <OneWire.h> // http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip
#include <DallasTemperature.h> // http://download.milesburton.com/Arduino/MaximTemperature/DallasTemperature_LATEST.zip
#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
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature
void setup() {
Serial.begin(9600);
pinMode(ONE_WIRE_POWER, OUTPUT); // set power pin for DS18B20 to output
}
void loop() {
digitalWrite(ONE_WIRE_POWER, HIGH); // turn DS18B20 sensor on
delay(5); // Allow 5ms for the sensor to be ready
sensors.begin(); //start up temp sensor
sensors.requestTemperatures(); // Get the temperature
int temp = (sensors.getTempCByIndex(0)*100); // Read first sensor and convert to integer, reversed at receiving end
Serial.println(temp);
digitalWrite(ONE_WIRE_POWER, LOW); // turn DS18B20 off
delay(5000);
}
Die Sensoradresse kann entfallen, ich glaube zumindest wenn man nur einen Sensor angeschlossen hat.
Wieder nur ein Minuswert, der unverändert bleibt. Hier mein kompletter Code, den ich in Verbindung mit einem NRF24L01+-Funkmodul nutze. Die Funkkommunikation läuft schon wunderbar, der DS18S20 hingegen nicht.
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <SPI85.h>
#include <Mirf85.h>
#include <nRF24L0185.h>
#include <MirfHardwareSpiDriver85.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 0 // DS18B20 Temperature sensor is connected on D10/ATtiny pin 13
#define ONE_WIRE_POWER 1 // DS18B20 Power pin is connected on D9/ATtiny pin 12
// 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);
int bufferSize = 0;
char buffer[6] = "";
uint16_t counter = 0;
uint8_t nodeID = 0;
#define CE PA2 //ATTiny
#define CSN PA3 //ATTiny
void setup(){
pinMode(0, OUTPUT);
Mirf.cePin = CE;
Mirf.csnPin = CSN;
Mirf.spi = &MirfHardwareSpi;
Mirf.init();
// This address is compatible with my example of rpi-hub or nRF24_Arduino_as_hub
// at repo https://github.com/stanleyseow/RF24/examples/
byte RADDR[] = {0xe2, 0xf0, 0xf0, 0xf0, 0xf0};
byte TADDR[] = {0xe3, 0xf0, 0xf0, 0xf0, 0xf0};
// Get nodeID from TXADDR and mask the first byte (0xff)
nodeID = *TADDR & 0xff;
Mirf.channel = 0x4c; // Same as rpi-hub and sendto_hub
Mirf.rfsetup = 0x06; // 1Mbps, Max power
Mirf.setRADDR(RADDR);
Mirf.setTADDR(TADDR);
Mirf.config();
// Enable dynamic payload
Mirf.configRegister( FEATURE, 1<<EN_DPL );
Mirf.configRegister( DYNPD, 1<<DPL_P0 | 1<<DPL_P1 | 1<<DPL_P2 | 1<<DPL_P3 | 1<<DPL_P4 | 1<<DPL_P5 );
delay(100);
// Print out register readinds for important settings
uint8_t rf_ch, rf_setup = 0;
byte tx_addr[5];
byte rx_addr[5];
Mirf.readRegister(RF_CH, &rf_ch,sizeof(rf_ch));
Mirf.readRegister(RF_SETUP, &rf_setup, sizeof(rf_setup));
Mirf.readRegister(TX_ADDR, tx_addr, sizeof(tx_addr));
Mirf.readRegister(RX_ADDR_P1, rx_addr, sizeof(rx_addr));
pinMode(ONE_WIRE_POWER, OUTPUT); // set power pin for DS18B20 to output
}
void loop(){
uint8_t sent = false;
uint8_t sensor1;
digitalWrite(ONE_WIRE_POWER, HIGH); // turn DS18B20 sensor on
delay(5); // Allow 5ms for the sensor to be ready
sensors.begin(); //start up temp sensor
sensors.requestTemperatures(); // Get the temperature
int temp = (sensors.getTempCByIndex(0)*100); // Read first sensor and convert to integer, reversed at receiving end
sprintf(buffer,"%04de,%06d",temp,counter++);
Mirf.payload = strlen(buffer);
Mirf.send((byte *) buffer);
while( Mirf.isSending() )
{
delay(1);
sent = true; // Sent success
}
digitalWrite(ONE_WIRE_POWER, LOW); // turn DS18B20 off
delay(500);
} // End loop()
An welchem Pin hängt denn dein Temperatursensor, am ATtiny Pin11 wie im ersten Post beschrieben? ONE_WIRE_BUS müsste dann evtl. auf 1 gesetzt werden?
Aktuell hast du ONE_WIRE_BUS auf 0 und im Setup wird 0 auch noch als OUTPUT festgelegt, da passt was nicht...
Übrigends, sofern du die Spannungsversorgung vom Sensor direkt an Plus angeschlossen hast, kannst du auch ONE_WIRE_POWER weglassen und musst den Sensor nicht immer ein- und ausschalten. Ansonsten hilft es beim Stromsparen, wenn man die Schaltung mit Batterie betreiben möchte.
Ja, -127°C wird mir angezeigt, woher weißt du das?
Der Power-Pin des DS18S20 hängt an Pin 12 (PA 1), der Daten-Pin an Pin 13 (PA 0) und Ground an Pin 14 des ATtinys. Power- und Daten - Pin des Sensors sind zudem noch mit einem 4,7kOhm-Widerstand verbunden.
Den Fehler mit ONE_WIRE_BUS und OUTPUT auf 0 habe ich korrigiert.
Der Wert von -127°C wird glaube ich angezeigt, wenn der Sensor nicht erkannt wird. Also entweder einen defekten Sensor oder falsch angeschlossen... Ich vermute mal mit deiner Pin-Zuordnung stimmt was nicht, da hatte ich anfangs auch noch irgendwie Probleme.
Welche Library nimmst du denn für den ATtiny? Bei mir ist die Zuordnung folgendermaßen (laut pins_arduino.c):
Wenn du die Pins 12 und 13 verwendest, musst du es auch so definieren:
#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
In deinem Code verwendest du für den BUS 0 und für POWER 1...
Meine pins_arduino.c sieht genau so aus... Ich teste den richtigen Pin meistens mit ner gewöhnlichen LED, wenn ich jetzt auf D9 / D10 umstelle, bekomme ich jedenfalls auf Pin 12 und 13 keine Spannung. Habe dann trotzdem mal den Temperatur-Sensor drangehängt, welcher mir hierfür gar keinen Wert mehr ausspuckt. Mit 0 und 1 kam wenigstens der -127 und meine LED blinkte auch wild. Ich denke mal, dass das was mit dem Port-A-Mapping zu tun hat, da mein Funkmodul auch auf Port A agiert.
Ich habe gerade auf 'nem Breadboard einen DS18B20-Sensor an einen ATtiny84 angeschlossen und nochmal rumgespielt. Habe mir die Temperatur über die serielle Schnittstelle anzeigen lassen, der von mir gepostete Code funktioniert bei mir problemlos, wenn die OneWire-Verbindung am Pin 13 angeschlossen wurde. Wenn ich den ONE_WIRE_BUS auf 0 setzte kam nur Müll dabei raus.
Ist überhaupt kein Sensor angeschlossen, erhalte ich 0°C. Ein Wert von -127°C wird mir dann angezeigt, wenn ich im Code noch die Sensoradresse hinzufüge und dabei eine falsche Adresse verwende, also wenn der Sensor unter der Adresse nicht gefunden wird. Der Code mit Sensoradresse wäre folgender:
#include <OneWire.h> // http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip
#include <DallasTemperature.h> // http://download.milesburton.com/Arduino/MaximTemperature/DallasTemperature_LATEST.zip
#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
OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance
DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature
DeviceAddress Tempsensor = { 0x18, 0xB0, 0xC1, 0x24, 0x03, 0x00, 0x00, 0xB5 }; <<< anpassen!!!
void setup() {
Serial.begin(9600);
pinMode(ONE_WIRE_POWER, OUTPUT); // set power pin for DS18B20 to output
// sensors.setResolution(Tempsensor, 10); // optional, Sensorauflösung anpassen
}
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress); //alternativ(??) sensors.temp=(sensors.getTempCByIndex(0)*1000); // Read first sensor and convert to integer, reversed at receiving end
if (tempC == -127.00) {
Serial.println("Error getting temperature");
} else {
Serial.print(tempC);
Serial.println(" Grad Celcius");
}
}
void loop() {
digitalWrite(ONE_WIRE_POWER, HIGH); // turn DS18B20 sensor on
delay(5); // Allow 5ms for the sensor to be ready
sensors.begin(); //start up temp sensor
sensors.requestTemperatures(); // Get the temperature
printTemperature(Tempsensor);
digitalWrite(ONE_WIRE_POWER, LOW); // turn DS18B20 off
delay(2000);
}
Vielleicht wäre es ja auch mal ein Versuch wert, ohne Funkmodul zu testen?
Die Unterschiede mit den ATtiny-Pins habe ich jetzt gelöst. Waren irgendwelche veralteten / anderen ATtiny-core-Files. Mit den Aktuellen liegt bei mir der softwaretechnische Pin 10 auch auf Pin 13 des ATtinys. Außerdem habe ich die OneWire - und die DallasTemperature - Library aktualisiert.
Zuerst habe ich deinen Sketch direkt am Arduino Uno getestet, welcher mir eine realistische Temperatur ausspuckt. Also prinzipiell dürften Libraries und dein Code soweit passen. Auch mein DS18S20-Sensor müsste soweit funktionieren. Am ATtiny hingegen, spuckt mir dein Code schön den Error aus, somit wieder die -127°C. Habe dein Code soweit modifiziert, dass ich keine Sensoradresse benötige. Zur Sicherheit habe ich den ATtiny selbst noch ausgewechselt, wodurch das identische Ergebnis hervortritt.
0°C bekomme ich eigentlich nur wenn der 4,7kOhm - Widerstand zwischen VCC und DATA fehlt bzw. der Pin 13 des ATtiny absolut keine Verbindung hat. Ob der DS18S20 dranhängt, oder nur der Widerstand, macht bei mir im Ergebnis keinen Unterschied. Ebenso habe ich das Funkmodul herausgelassen, lese jetzt die Werte ebenfalls über Serial aus.
Habe mir von einem Kollegen einen DS18B20 besorgt, da dies mein einziger Anhaltspunkt noch war, dass sich dort minimale Unterschiede ergeben. Aber leider funktioniert dieser auch nicht, ebenfalls -127°C. Hab mir echt nicht gedacht, dass der Temperatursensor so Probleme macht, da ja das Funkmodul auch super läuft, wie auch alles andere, was ich mit dem ATtiny realisiert habe.
Hmm da du ja anscheinend kein grundsätzliches Problem weder mit dem Sensor noch mit dem ATtiny hast, bin ich somit leider auch ratlos... Vielleicht eine zu geringe Versorgungsspannung? Der Sensor braucht laut Datenblatt mindestens 3V.
Die Arduino IDE wird wahrscheinlich auch keinen Einfluß haben, oder? Ich hatte die 1.0.3 und glaube zuletzt auch die 1.0.4 verwendet.
Hallo,
ich hatte das gleiche Problem der ds18b20 würde nicht erkannt, darum immer die -127. Nach langem suchen den Bootloader installiert und siehe da es geht
lg markus