Пересчёт количества импульсов и измерение температуры

APJ
Offline
Зарегистрирован: 25.03.2015
#include <avr\interrupt.h>
#include <OneWire.h>
#include <DallasTemperature.h>

char count = 0, mode = 0;
char ledPin = 13;&nbsp; //input D2,Output 13

#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Thermometer1 = { 
&nbsp; 0x28, 0xFF, 0xD7, 0x8D, 0x64, 0x14, 0x01, 0xB1 };&nbsp; //&nbsp; DS18B20 adress

int hbtemp ; 
int sval;

long previousMillis = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;long interval = 1000;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 

void setup() { 
sensors.begin();
&nbsp; sensors.setResolution(Thermometer1, 10);&nbsp; 
DDRD &= 0xFB;
PORTD &= 0xFB;
pinMode(ledPin, OUTPUT); 
digitalWrite(13, HIGH);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // включить подтягивающий резистор
&nbsp; pinMode(6, OUTPUT);
Serial.begin(9600); 
mode = 0;
count = 0;

EICRA = (1 << ISC00);
EIFR = 0xFF;
EIMSK = (1 << INT0);
asm("sei"); 


&nbsp;TCCR1B = TCCR1B & 0b11111000 | 0x02;
}


void printTemperature(DeviceAddress deviceAddress) {
&nbsp; float tempC = sensors.getTempC(deviceAddress);

&nbsp; 
&nbsp;analogWrite(6,290-hbtemp);
&nbsp;Serial.println(tempC);
Serial.println(hbtemp);

if (tempC<=45);{
&nbsp;hbtemp=(4*tempC);
&nbsp;}


}
void loop() 
{
}
ISR(INT0_vect) { //* signal handler for external interrupt int0 */
switch(mode)
{
case 0:
&nbsp; 
count++;
if (count < 8) { digitalWrite(ledPin, LOW); }
else {count = 0; digitalWrite(ledPin, HIGH); mode = 1; }

&nbsp;
break;
&nbsp;case 1:
&nbsp;count++;
&nbsp;if (count < 8) { digitalWrite(ledPin, HIGH); }
&nbsp;else {count = 0; digitalWrite(ledPin, LOW); mode = 0; }
unsigned long currentMillis = millis();
&nbsp; if(currentMillis - previousMillis > interval) {
&nbsp; previousMillis = currentMillis; 
sensors.requestTemperatures();
printTemperature(Thermometer1);
&nbsp;}
&nbsp;break;
}
}

Добрый день

Подскожите с кодом, требуется дилить входные импульсы на 8, что реализовано, и брать данные с термометра примерно раз в секунду и выводить их с PWM выхода в аналогом виде, что тоже работает. Проблема возникает если на вход не поступают импульсы, в это время измерения температуры должны так-же работать. А сейчас всё стопориться в ожидании сигнала. Скажите, как это можно исправить.

 

APJ
Offline
Зарегистрирован: 25.03.2015
#include <avr\interrupt.h>
#include <OneWire.h>
#include <DallasTemperature.h>

char count = 0, mode = 0;
char ledPin = 13;  //input D2,Output 13

#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Thermometer1 = { 
  0x28, 0xFF, 0xD7, 0x8D, 0x64, 0x14, 0x01, 0xB1 };  // адрес датчика DS18B20

int hbtemp ; 
int sval;

long previousMillis = 0;         
long interval = 1000;           


// the setup routine runs once when you press reset:
void setup() { 
sensors.begin();
  sensors.setResolution(Thermometer1, 10);  
DDRD &= 0xFB;
PORTD &= 0xFB;
pinMode(ledPin, OUTPUT); 
digitalWrite(13, HIGH);       // включить подтягивающий резистор
  pinMode(6, OUTPUT);
Serial.begin(9600); 
mode = 0;
count = 0;

EICRA = (1 << ISC00);
EIFR = 0xFF;
EIMSK = (1 << INT0);
asm("sei"); 

 TCCR1B = TCCR1B & 0b11111000 | 0x02;
}


void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);

 analogWrite(6,290-hbtemp);
 Serial.println(tempC);
Serial.println(hbtemp);

if (tempC<=45);{
 hbtemp=(4*tempC);
 }


}
void loop() 
{
}
ISR(INT0_vect) { //* signal handler for external interrupt int0 */
switch(mode)
{
case 0:
  
count++;
if (count < 8) { digitalWrite(ledPin, LOW); }
else {count = 0; digitalWrite(ledPin, HIGH); mode = 1; }

 
break;
 case 1:
 count++;
 if (count < 8) { digitalWrite(ledPin, HIGH); }
 else {count = 0; digitalWrite(ledPin, LOW); mode = 0; }
unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
  previousMillis = currentMillis; 
sensors.requestTemperatures();
printTemperature(Thermometer1);
 }
 break;
}
}

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

pinMode(ledPin, OUTPUT);
digitalWrite(13, HIGH);

Это вам резистор не включит. Это включит светодиод.

http://arduino.cc/en/Reference/PinMode

APJ
Offline
Зарегистрирован: 25.03.2015

trembo пишет:

pinMode(ledPin, OUTPUT);
digitalWrite(13, HIGH);

Это вам резистор не включит. Это включит светодиод.

http://arduino.cc/en/Reference/PinMode

Спасибо, незаметил

Наверное так корректно-

digitalWrite(02, HIGH);       // включить подтягивающий резистор

Но сути это никак не меняет, как заставить её мерить температуру

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011
APJ
Offline
Зарегистрирован: 25.03.2015

Как я понию эти библиотеки являются заменой Delay или mills, так что они мне  не помогут. У меня программа останавливается в ожидании импульса, надо что-то что работало бы независимо от счёта 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

1. Это не замена ничему. Это простая и понятная работа с миллисом.

2. А вы не думали о том что программу лучше вообще никогда не останавливать ни на какие ожидания?
  Программа должна крутится без остановок, в определённые времена что-то совершать, а внешние входы должны вызывать прерывания.

APJ
Offline
Зарегистрирован: 25.03.2015

2. Я знаю это, но не знаю как это организовать. Поэтому и создал тему.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

В лупе     if ( millis() - previousmillis >=5000)  { меряем температуру раз в 5 секунд}

или      

timer.setInterval(5000, RepeatTask); 

void RepeatTask() { меряем температуру раз в 5 секунд}

Опрашивать датчик часто- это значит греть его.....

Если датчик один - не используют его серийный номер- читают тот что  есть

APJ
Offline
Зарегистрирован: 25.03.2015

Сделал ещё вчера, непонимаю почему до этого не работало так. Вроде пробовал. Спасибо помощь.

#include <avr\interrupt.h>
#include <OneWire.h>
#include <DallasTemperature.h>

char count = 0, mode = 0;
char ledPin = 13;  //input D2,Output 13

#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress Thermometer1 = { 
  0x28, 0xFF, 0xD7, 0x8D, 0x64, 0x14, 0x01, 0xB1 };  // адрес датчика DS18B20

int hbtemp ; 
int sval;

long previousMillis = 0;        // храним время последнего переключения светодиода
 
long interval = 1000;           // интервал между включение/выключением светодиода (1 секунда)



// the setup routine runs once when you press reset:
void setup() { 
sensors.begin();
  sensors.setResolution(Thermometer1, 10);  
DDRD &= 0xFB;
PORTD &= 0xFB;
pinMode(ledPin, OUTPUT); 
digitalWrite(02, HIGH);       // включить подтягивающий резистор
  pinMode(6, OUTPUT);
Serial.begin(9600); 
mode = 0;
count = 0;

EICRA = (1 << ISC00);
EIFR = 0xFF;
EIMSK = (1 << INT0);
asm("sei"); 

  
 TCCR1B = TCCR1B & 0b11111000 | 0x02;
}

 
void printTemperature(DeviceAddress deviceAddress) {
  float tempC = sensors.getTempC(deviceAddress);

  
// hbtemp=(tempC*4);
 analogWrite(6,290-hbtemp);
 Serial.println(tempC);
Serial.println(hbtemp);

if (tempC<=45);{
 hbtemp=(4*tempC);
 }

}
void loop() 
{
unsigned long currentMillis = millis();
   if(currentMillis - previousMillis > interval) {
  previousMillis = currentMillis; 
sensors.requestTemperatures();
printTemperature(Thermometer1);
   }
}
ISR(INT0_vect) { //* signal handler for external interrupt int0 */
switch(mode)
{
case 0:
  
count++;
if (count < 2) { digitalWrite(ledPin, LOW); }
else {count = 0; digitalWrite(ledPin, HIGH); mode = 1; }

 break;
 
 case 1:
 count++;
 if (count < 2) { digitalWrite(ledPin, HIGH); }
 else {count = 0; digitalWrite(ledPin, LOW); mode = 0; }

break;
 
}  
   }

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Вот о чём я писал:  При одном термометре не использовать его адрес.
Допустим если вы поменяете его на другой-  выяснять адрес нового и компилить-прошиваться по новой?
А если их два-три? Ещё и разбираться ху-ис-ху?
Укороченый пример библиотеки: Читаем то что есть. Надо другой- сажаем на другой пин.

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup(void){
  Serial.begin(9600);
  sensors.begin();
}
void loop(void){
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(sensors.getTempCByIndex(0));  
}