Hallo zusammen,
Ich bin absolut neu in diesem Forum und hoffe, dass ihr mir eventuell weiterhelfen könnt!
Ich möchte mit meinem arduino mega vier Temperatursensoren welche jeweils an einem Max6675 angeschlossen sind betreiben!
Meine Fragen an euch:
Besten Dank für eure Hilfe
Hallo,
die werden am SPI Bus angeschlossen.
An SO und CLK alle gemeinsam und jeder bekommt eine CS Leitung für sich.
Spannung und Masse ist klar.
Dann liest du sie im minimalen Abstand von 220ms aus.
Mit Google findest du auch eine Library. "Arduino max6675"
Danke für deine schnelle Antwort!
Habe sie wie beschrieben angeschlossen.
Wenn ich eine Library für den Max6675 suche finde ich immer nur welche mit einem und nicht mit mehreren!
Das musst du dir selbst zusammenbasteln. Zeig mal den Sketch den du momentan hast.
Gruß
agmue
July 19, 2016, 6:22am
5
Du nutzt mehrere Instanzen der Bibliothek:
MAX6675 thermocouple1(thermoCLK, thermoCS1, thermoDO);
MAX6675 thermocouple2(thermoCLK, thermoCS2, thermoDO);
MAX6675 thermocouple3(thermoCLK, thermoCS3, thermoDO);
MAX6675 thermocouple4(thermoCLK, thermoCS4, thermoDO);
...
Serial.println(thermocouple4.readCelsius());
Hier ist ein ausschnitt aus dem Programm was ich bis jetzt habe:
void loop()
{
Mb.Run();
if (flag==1)
{
switch (chipselect)
{
case 1:
sensoren_auslesen1 (&t1);
sensoren_wertuebergabe_raspi(t1, t2, t3, t4);
chipselect=2;
break;
case 2:
sensoren_auslesen2 (&t2);
sensoren_wertuebergabe_raspi(t1, t2, t3, t4);
chipselect=3;
break;
case 3:
sensoren_auslesen3 (&t3);
sensoren_wertuebergabe_raspi(t1, t2, t3, t4);
chipselect=4;
break;
case 4:
sensoren_auslesen4 (&t4);
sensoren_wertuebergabe_raspi(t1, t2, t3, t4);
chipselect=1;
break;
}
// Serial.println(t1);
flag=0;
}
//***************************************************************************************************
int sensoren_auslesen1( int *t1)
{
unsigned int v;
digitalWrite(cs1, LOW);
delay(1);
v = spiread();
v <<= 8;
v |= spiread();
digitalWrite(cs1, HIGH);
if (v & 0x4) {
// uh oh, no thermocouple attached!
return NAN;
//return -100;
}
v >>= 3;
return *t1 = (int)v*0.25;
}
//***************************************************************************************************
int sensoren_auslesen2( int *t2)
{
unsigned int v;
digitalWrite(cs2, LOW);
delay(1);
v = spiread();
v <<= 8;
v |= spiread();
digitalWrite(cs2, HIGH);
if (v & 0x4) {
// uh oh, no thermocouple attached!
return NAN;
//return -100;
}
v >>= 3;
return *t2 = (int)v*0.25;
}
//***************************************************************************************************
//***************************************************************************************************
int sensoren_auslesen3( int *t3)
{
unsigned int v;
digitalWrite(cs3, LOW);
delay(1);
v = spiread();
v <<= 8;
v |= spiread();
digitalWrite(cs3, HIGH);
if (v & 0x4) {
// uh oh, no thermocouple attached!
return NAN;
//return -100;
}
v >>= 3;
return *t3 = (int)v*0.25;
}
//***************************************************************************************************
int sensoren_auslesen4( int *t4)
{
unsigned int v;
digitalWrite(cs4, LOW);
delay(1);
v = spiread();
v <<= 8;
v |= spiread();
digitalWrite(cs4, HIGH);
if (v & 0x4) {
// uh oh, no thermocouple attached!
return NAN;
//return -100;
}
v >>= 3;
return *t4 = (int)v*0.25;
}
//***************************************************************************************************
//***************************************************************************************************
void sensoren_wertuebergabe_raspi(int t1,int t2,int t3, int t4)
{
Mb.R[8]=t1;
Mb.R[9]=t2;
Mb.R[10]=t3;
Mb.R[11]=t4;
//Mb.R[12]=0; // Reserve nicht verwendet
//Mb.R[13]=0; // Reserve nicht verwendet
//Mb.R[14]=0; // Reserve nicht verwendet
// Mb.R[15]=0; // Reserve nicht verwendet
}
//***************************************************************************************************
Wo wird "flag" denn gesetzt?
Am Anfang vom Programm ist in dem Ausschnitt nicht drauf
//Hilfsvariablen
int sensor_daten_aktu=10;
bool flag=1;
@ agmue habe deinen vorschlag mal ausprobiert hier der Code:
#include "max6675.h"
int thermoDO = 22;
int thermoCS1 = 24;
int thermoCS2 = 25;
int thermoCS3 = 26;
int thermoCS4 = 27;
int thermoCLK = 23;
MAX6675 thermocouple11(thermoCLK, thermoCS1, thermoDO);
MAX6675 thermocouple12(thermoCLK, thermoCS2, thermoDO);
MAX6675 thermocouple13(thermoCLK, thermoCS3, thermoDO);
MAX6675 thermocouple14(thermoCLK, thermoCS4, thermoDO);
void setup() {
Serial.begin(9600);
// use Arduino pins
Serial.println("MAX6675 test");
// wait for MAX chip to stabilize
delay(500);
}
void loop() {
// basic readout test, just print the current temp
Serial.print("C1 = ");
Serial.println(thermocouple11.readCelsius());
Serial.print("C2 = ");
Serial.println(thermocouple12.readCelsius());
Serial.print("C3 = ");
Serial.println(thermocouple13.readCelsius());
Serial.print("C4 = ");
Serial.println(thermocouple14.readCelsius());
delay(1000);
}
Bekomme aber keine realistischen Werte auf dem Seriellen Monitor angezeigt
C1 = 0
C2 = 1343
C3 = 0
C4 = 0
C1 = 63
C2 = 0
C3 = 0
C4 = 1039
C1 = 0
C2 = 0
C3 = 0
C4 = 1795
C1 = 0
C2 = 0
C3 = 543
C4 = 0
C1 = 0
C2 = 62
C3 = 0
C4 = 0
C1 = 0
C2 = 1567
C3 = 0
C4 = 0
C1 = 63
C2 = 0
C3 = 0
C4 = 1543
Ich hab mal kurz diese library : MAX6675-library/max6675.cpp at master · adafruit/MAX6675-library · GitHub angesehen.
Da liefert readCelsius() ein double zurück.
Danach sieht es in deiner Testausgabe nicht aus, denn da würde ich bei deinem Sketch sowas wie
C1 = 22.34
erwarten.
Was verbirgt sich hinter deinem #include "max6675.h" ?
Mit einem einzigen Sensor gehts?
das ist in meiner max6675.cpp
// this library is public domain. enjoy!
// www.ladyada.net/learn/sensors/thermocouple
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include "max6675.h"
MAX6675::MAX6675(int8_t SCLK, int8_t CS, int8_t MISO) {
sclk = SCLK;
cs = CS;
miso = MISO;
//define pin modes
pinMode(cs, OUTPUT);
pinMode(sclk, OUTPUT);
pinMode(miso, INPUT);
digitalWrite(cs, HIGH);
}
int MAX6675::readCelsius(void) {
double MAX6675::readCelsius(void) {
uint16_t v;
digitalWrite(cs, LOW);
_delay_ms(1);
v = spiread();
v <<= 8;
v |= spiread();
digitalWrite(cs, HIGH);
if (v & 0x4) {
// uh oh, no thermocouple attached!
return NAN;
//return -100;
}
v >>= 3;
int a;
return a = (int)v*0.25;
}
byte MAX6675::spiread(void) {
int i;
byte d = 0;
for (i=7; i>=0; i--)
{
digitalWrite(sclk, LOW);
_delay_ms(1);
if (digitalRead(miso)) {
//set the bit to 0 no matter what
d |= (1 << i);
}
digitalWrite(sclk, HIGH);
_delay_ms(1);
}
return d;
}
Dies ist in meiner max6675.h
// this library is public domain. enjoy!
// www.ladyada.net/learn/sensors/thermocouple
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
class MAX6675 {
public:
MAX6675(int8_t SCLK, int8_t CS, int8_t MISO);
int readCelsius(void);
Zeile double readCelsius(void);
private:
int8_t sclk, miso, cs;
uint8_t spiread(void);
};
enjoy!
Danke, aber
das ist in meiner max6675.cpp
stimmt wohl nicht so ganz, hoffentlich
digitalWrite(cs, HIGH);
}
int MAX6675::readCelsius(void) {
double MAX6675::readCelsius(void) {
uint16_t v;
so sieht es wohl nicht genau aus.
www.ladyada.net/learn/sensors/thermocouple
Wenn man sich von diesem toten Link aus weiterhangelt, kommt man schon bei der github adafruit library raus.
Hallo,
ich würde es bei dem Teil ganz ohne Lib machen. Man braucht eh nur eine kleine Funktion und ruft diese immer mit dem übergebenen CS Pin auf. Kannst auch noch globale float Variablen nutzen um die Temperaturwerte zu verarbeiten und nicht nur direkt auszugeben.
// add this to the top of your sketch
#define NOP __asm__ __volatile__ ("nop\n\t")
#include <SPI.h>
const byte MAX1_CS = 24; // CS pin 24
const byte MAX2_CS = 25;
const byte MAX3_CS = 26;
// SO pin 50 Mega 2560
// CLK pin 52 Mega 2560
void setup() {
Serial.begin(9600);
//SPI.setBitOrder(MSBFIRST);
//SPI.setClockDivider(SPI_CLOCK_DIV8); // wären 2 MHz SPI Takt
//SPI.setDataMode(SPI_MODE0); // DataMode 0
SPI.begin();
pinMode(53, OUTPUT); // wegen SPI Funktion notwendig
digitalWrite(MAX1_CS, HIGH); // CS High Pegel
digitalWrite(MAX2_CS, HIGH);
digitalWrite(MAX3_CS, HIGH);
pinMode(MAX1_CS, OUTPUT); // CS Pin Ausgang
pinMode(MAX2_CS, OUTPUT);
pinMode(MAX3_CS, OUTPUT);
}
void loop()
{
Serial.println(MAX_6675(MAX1_CS),2);
Serial.println(MAX_6675(MAX2_CS),2);
Serial.println(MAX_6675(MAX3_CS),2);
delay(2000); // typisch sind 220ms erforderlich
}
float MAX_6675(int CS)
{
unsigned int KTemp = 0;
float Celius = 0;
digitalWrite(CS, LOW);
NOP; // delay 62.5ns on a 16MHz AtMega, 100ns erforderlich
NOP;
byte MSB = SPI.transfer(0); // höherwertiges Byte einlesen, D15 ... D8
byte LSB = SPI.transfer(0); // niederwertiges Byte einlesen, D7 ... D0
digitalWrite(CS, HIGH);
KTemp = MSB << 8;
KTemp = KTemp | LSB;
KTemp = KTemp >> 3;
Celius = (float) (KTemp * 0.25);
return Celius;
}
Hallo Doc_Arduino,
habe nun endlich deinen Code ausprobieren können!
Leider bekomme ich leider keine realistischen Temperaturen angezeigt!
Hallo,
seltsam. Aufbau und Verkabelung ist i.O.?
Sketch wird Fehlerfrei übersetzt?
Haste den Code verändert?
Welchen Arduino hast du?
ich habe deinen Code kopiert und in ein leeres Projekt eingefügt.
Die Verkabelung habe ich so:
Alle drei CLK gebrückt und an Pin 52 angeschlossen.
Alle drei SO gebrückt und an Pin 50 angeschlossen.
MAX1_CS = 24
MAX2_CS = 25
MAX3_CS = 26
Ich besitze den Arduino Mega 2560
in deinem Code ist das SO und CLK auskommentiert liegt es eventuell daran ?
ansonsten habe ich deinen code eins zu eins verwendet
übersetzen funktioniert ohne fehler
Hallo,
okay, da muß ich später nochmal im Ruhe zu Hause schauen.
Die vermeindliche Auskommentierung ist keine Auskommentierung, soll ein reiner Kommentar sein, damit man weis was wo angeklemmt wird, die Pinfunktionen werden automatisch aktiv wenn man im setup spi.begin aktiviert.
okay, wäre sehr cool, wenn du nochmal nach schauen könntest
Hallo,
jetzt bin echt ratlos. Habe es mit meinen 2 MAXen aufgebaut und es funktioniert wie erwartet.
Raumtemperatur stimmt und reagiert auf Handwärme.
Was bekommste denn für Temperaturwerte angezeigt und welche werden erwartet?
Mach mal bitte ein Foto von deinen MAX Platinen und Fühlern.
Ein Sketch mit der fertigen Lib funktioniert?
Hallo,
und siehe da, nach einer Weile spinnt ein Sensor rum. Raumtemp. angeblich 49°C und mit Berührung gehts runter auf 36°C und dann wieder rauf. Nach weiteren probieren entpuppte sich eine Lötstelle als Ursache vom Thermokabel. Eigentlich soll man die nicht löten, ich weiß das, ist aber nur ein Versuchsaufbau. Nachgelötet und alles wieder schick. Also schau mal nach Kontaktproblemen. Übrigens kannste noch den SPI-Mode1 aktivieren. Das wäre richtiger. An den Werten ändert das aber nichts bei mir.