Толян ©:zcom ©:....Финальная на сегодня доработка скетча.....
Скетч из сообщения копируется с ошибками
С ошибками? Странно, конечно. Может не все копируете? Или, наоборот, что-то лишнее прихватывается? Вот, проверенный вариант. На днях появится обновленный вариант для измененной БК с черновым расчетом поглощаемого димротом тепла в реальном времени. Не знаю, на сколько этот расчет будет соответствовать действительности, но хотя бы в первом приближении будет интересно посмотреть.
#include <OneWire.h>
#include <memorysaver.h>
#include <UTFT.h>
#define PIN_CONNECT 10 // on pin 10 (a 4.7K resistor is necessary)
#define SERIAL_BAUD 115200 //
#define TS_PERIOD 1000 //
#define TS_RESOLUTION 12 // 9, 10, 11, 12 bit
#define SENSORS 6 //
#define TOP_COLUMN "28.F6.29.01.00.00.80.D6"
#define MIDDLE_COLUMN "28.F5.33.01.00.00.80.4E"
#define IN_WATER "28.B2.34.01.00.00.80.EF"
#define IN_DIMROT "28.13.29.01.00.00.80.14"
#define OUT_DIMROT "28.F4.DF.00.00.00.80.0D"
#define FREE_TS "28.12.29.01.00.00.80.23"
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
struct tsdata {
byte addr[8];
byte answer[9];
float tempC = -273.15;
float tempF = -273.15;
boolean enable = false;
boolean readable = false;
};
tsdata ts[SENSORS];
float tempC[SENSORS];
unsigned long count = 0;
byte operation = 1;
OneWire ds(PIN_CONNECT);
UTFT LCD(CTE32HR, 38, 39, 40, 41);
// from http://forum.arduino.cc/index.php?topic=37391.0 #9
char * floatToString(char * outstr, double val, byte precision, byte widthp){
char temp[16]; //increase this if you need more digits than 15
byte i;
temp[0]='\0';
outstr[0]='\0';
if(val < 0.0){
strcpy(outstr,"-\0"); //print "-" sign
val *= -1;
}
if( precision == 0) {
strcat(outstr, ltoa(round(val),temp,10)); //prints the int part
}
else {
unsigned long frac, mult = 1;
byte padding = precision-1;
while (precision--)
mult *= 10;
val += 0.5/(float)mult; // compute rounding factor
strcat(outstr, ltoa(floor(val),temp,10)); //prints the integer part without rounding
strcat(outstr, ".\0"); // print the decimal point
frac = (val - floor(val)) * mult;
unsigned long frac1 = frac;
while(frac1 /= 10)
padding--;
while(padding--)
strcat(outstr,"0\0"); // print padding zeros
strcat(outstr,ltoa(frac,temp,10)); // print fraction part
}
// generate width space padding
if ((widthp != 0)&&(widthp >= strlen(outstr))){
byte J=0;
J = widthp - strlen(outstr);
for (i=0; i< J; i++) {
temp[i] = ' ';
}
temp[i++] = '\0';
strcat(temp,outstr);
strcpy(outstr,temp);
}
return outstr;
}
char * ts_addr(char * outstr, byte i) {
sprintf(outstr, "%02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", ts[i].addr[0], ts[i].addr[1], ts[i].addr[2], ts[i].addr[3], ts[i].addr[4], ts[i].addr[5], ts[i].addr[6], ts[i].addr[7]);
return outstr;
}
char * ts_name(byte i, boolean shortName=false) {
char temp[22];
ts_addr(temp, i);
if (strcmp(temp, TOP_COLUMN)==0) {
if (shortName)
return "TOP";
else
return "top column";
}
if (strcmp(temp, MIDDLE_COLUMN)==0) {
if (shortName)
return "2/3";
else
return "2/3 column";
}
if (strcmp(temp, IN_WATER)==0) {
if (shortName)
return "WATER";
else
return "input water";
}
if (strcmp(temp, IN_DIMROT)==0) {
if (shortName)
return "DIMROT";
else
return "input dimrot";
}
if (strcmp(temp, OUT_DIMROT)==0) {
if (shortName)
return "outWATER";
else
return "output dimrot";
}
if (strcmp(temp, FREE_TS)==0) {
if (shortName)
return "FREE";
else
return "free sensor";
}
return '\0';
}
void ts_output_all_address(boolean s=true) {
byte i;
char temp[22];
for (i=0; i<SENSORS; i++) {
if (ts[i].enable) {
Serial.print("Device ");
Serial.print(i);
Serial.print(" = ");
Serial.println(ts_addr(temp, i));
}
}
}
void ts_init(boolean showMenu=true) {
byte i, j, n=0;
char temp[22];
ds.reset_search();
while (ds.search(ts[n].addr)) {
if (ds.crc8(ts[n].addr, 7) == ts[n].addr[7]) {
if ((ts[n].addr[0] == 0x10) || (ts[n].addr[0] == 0x22) || (ts[n].addr[0] == 0x28)) {
ts[n].enable = true;
ds.reset();
ds.select(ts[n].addr);
ds.write(0x4E);
ds.write(0);
ds.write(0);
switch (TS_RESOLUTION) {
case 9:
ds.write(0x1F);
case 10:
ds.write(0x3F);
case 11:
ds.write(0x5F);
default:
ds.write(0x7F);
}
ds.write(0x48);
n++;
if (n > SENSORS)
break;
}
}
}
if (showMenu) {
Serial.print("Number of sensors = ");
Serial.println(n);
for (i=0; i<SENSORS; i++) {
if (ts[i].enable) {
Serial.print("Device ");
Serial.print(i);
Serial.print(" = ");
Serial.println(ts_addr(temp, i));
}
}
if (n != 0) {
Serial.println("Menu:");
Serial.println("1 - Starts measurement");
Serial.println("2 - Starts diagnostics");
Serial.println("3 - Show sensors address");
Serial.println("0 - To stop all operations");
Serial.println("Choice?");
}
}
}
void ts_conv(void) {
byte i;
for (i=0; i<SENSORS; i++) {
if (ts[i].enable) {
ts[i].readable = false;
ds.reset();
ds.select(ts[i].addr);
ds.write(0x44);
}
}
}
void ts_read(void) {
byte i, j;
int16_t test;
float tC;
for (i=0; i<SENSORS; i++) {
if (ts[i].enable) {
ds.reset();
ds.select(ts[i].addr);
ds.write(0xBE);
for (j=0; j<9; j++) {
ts[i].answer[j] = ds.read();
}
ts[i].readable = (ds.crc8(ts[i].answer, 8) == ts[i].answer[8]);
test = ts[i].answer[1] * 256 + ts[i].answer[0];
if (ts[i].addr[0] == 0x10) {
test = test << 3;
if (ts[i].answer[7] == 0x10) {
test = (test & 0xFFF0) + 12 - ts[i].answer[6];
}
}
else {
switch (ts[i].answer[4] & 0x60) {
case 0x00:
test = test & ~7;
case 0x20:
test = test & ~3;
case 0x40:
test = test & ~1;
}
}
ts[i].tempC = (float)test / 16.0;
ts[i].tempF = ts[i].tempC * 1.8 + 32.0;
}
}
}
void ts_diag(void) {
byte i;
char temp[22];
for (i=0; i<SENSORS; i++)
if (abs(ts[i].tempC - tempC[i]) >= 5) {
Serial.print("Device ");
Serial.print(i);
Serial.print(" = ");
Serial.println(ts_addr(temp, i));
Serial.print(", resting temperature = ");
Serial.print(tempC[i]);
Serial.print("C, current temperature = ");
Serial.print(ts[i].tempC);
Serial.println("C");
}
}
void ts_output_serial(void) {
byte i;
Serial.print("ts_data,");
Serial.print(millis());
for (i=0; i<SENSORS; i++) {
if (ts[i].enable) {
Serial.print(",");
Serial.print(ts[i].tempC);
}
}
Serial.println();
}
void lcd_init(void) {
LCD.InitLCD(0);
LCD.clrScr();
}
void ts_output_lcd(void) {
byte i, b;
char text[7], buf[4], temp[22];;
int y;
LCD.setFont(BigFont);
LCD.print("Temperature", LEFT, 20);
for (i=0; i<SENSORS; i++) {
if (ts[i].enable) {
ts_addr(temp, i);
if (strcmp(temp, TOP_COLUMN)==0)
y = 50;
else if (strcmp(temp, MIDDLE_COLUMN)==0)
y = 105;
else if (strcmp(temp, IN_WATER)==0)
y = 170;
else if (strcmp(temp, IN_DIMROT)==0)
y = 225;
else if (strcmp(temp, OUT_DIMROT)==0)
y = 280;
else if (strcmp(temp, FREE_TS)==0)
y = 335;
else
y = 390;
LCD.setFont(SevenSegNumFont);
floatToString(text, ts[i].tempC, 2, 6);
if (text[0] = 32) {
buf[0] = text[1];
buf[1] = text[2];
buf[2] = '\0';
LCD.print(buf, 32, y);
}
else if (text[0] = '-') {
buf[0] = text[1];
buf[1] = text[2];
buf[2] = '\0';
LCD.print(buf, 32, y);
}
else {
buf[0] = text[0];
buf[1] = text[1];
buf[2] = text[2];
buf[3] = '\0';
LCD.print(buf, 0, y);
}
LCD.fillRect(102, y + 43, 106, y + 48);
buf[0] = text[4];
buf[1] = text[5];
buf[2] = '\0';
LCD.print(buf, 112, y);
LCD.setFont(BigFont);
LCD.print("ts", 184, y);
text[0] = char(49 + i);
text[1] = '\0';
LCD.print(text, 216, y);
LCD.print(ts_name(i, true), 184, y + 34);
}
}
}
void setup(void) {
Serial.begin(SERIAL_BAUD);
lcd_init();
ts_init(false);
ts_conv();
count = millis();
}
void loop(void) {
byte i, data;
char temp[22], text[7];
data = Serial.read();
if (data == 0x30) {
operation = 0;
Serial.println("Break of operation");
ts_init();
}
else if (data == 0x31) {
operation = 1;
lcd_init();
Serial.println("Running measurement");
}
else if (data == 0x32) {
operation = 2;
lcd_init();
Serial.println("Running diagnostics");
ts_read();
for (i=0; i<SENSORS; i++)
tempC[i] = ts[i].tempC;
}
else if (data == 0x33) {
operation = 3;
// Output serial
Serial.println("Show sensors address");
for (i=0; i<SENSORS; i++) {
if (ts[i].enable) {
Serial.print("Device ");
Serial.print(i);
Serial.print(" = ");
Serial.print(ts_addr(temp, i));
Serial.print(", ");
Serial.println(ts_name(i));
}
}
// Output lcd
lcd_init();
for (i=0; i<SENSORS; i++) {
if (ts[i].enable) {
LCD.setFont(BigFont);
LCD.print("ts =", 0, 30 + i*20);
text[0] = char(49 + i);
text[1] = '\0';
LCD.print(text, 32, 30 + i*20);
LCD.print(ts_addr(temp, i), 70, 30 + i*20);
}
}
}
if (operation == 1)
if ((millis() - count) >= TS_PERIOD) {
count = millis();
ts_read();
ts_output_serial();
ts_output_lcd();
ts_conv();
}
if (operation == 2)
if ((millis() - count) >= TS_PERIOD) {
count = millis();
ts_read();
ts_diag();
ts_conv();
}
}
Вопросы по коду задавайте, отвечу.
Толян ©:Еще бы сразу к нему и схему подключения приложить, таким как я, "ардунщикам" в кавычках, очень бы помогло.
Схему надо нарисовать. Тут вы правы. Но ее пока нет.
Словесное описание. Я использую Arduino Due, схема и скетч подойдет и для Arduino Mega2560. Используется сама тушка, на нее одевается TFT-дисплей 480х320 точек (покупал в Амперке, он там один такой). Далее на 10 контакт PWM одевается проводник, соединяются сигнальные линии всех датчиков температуры в одну линию, подключаются к этому проводнику. Далее с платы Ардуины забираю "землю" (GND) и питание (+3,3В для Due и +5 для Mega2560). Также соответствующие провода датчиков в одну шину и к ним питание и землю. Между сигнальным проводом и питанием припаиваем резистор на 4,7кОм. Вроде как все.
Недостающие библиотеки для скетча скачиваем с github. Ищем через google, например.

Это общий вид сборки без датчиков. Датчики подключаются через разъемы.

Вот монтажная плата с разъемами и резистором.

Это уже готовый к работе вариант. Тоже без датчиков (просто они на колонне закреплены, не снять просто так).