Подключение логометра

kitay-k
Offline
Зарегистрирован: 15.01.2017

Привет всем. Начинаю пробовать свои силы в программировании. Появилась задача сделать указатель температуры на логометре на  датчике Ds18b20, на просторах интернета нашел скетч, попробовал его залить, но логометр не реагирует на изменение температуры, хотя калибровка работает. Помогите разобраться, что не так.

#include <OneWire.h>
OneWire  ds(2); // пин датчика температуры
byte addr[8]={0x28, 0xA0, 0xC7, 0x26, 0x00, 0x00, 0x80, 0xC4}; //адрес датчика температуры

//this is the maximum resolution of the PWM output.
const int maxAnalogRes = 255;

const int aircore1SinDirPin1 = 3;  //sin+ these two control the polarity to the "sine" coil
const int aircore1SinDirPin2 = 5;  //sin-
const int aircore1CosDirPin1 = 11; //cos+ these two control the polarity to the "cosine" coil
const int aircore1CosDirPin2 = 6;  //cos-

float wTemp;
byte flagDallRead;

void setup()
{
 TCCR2B = TCCR2B & 0b11111000 | 0x01;
 TCCR0B = TCCR0B & 0b11111000 | 0x01;
 //Set the pins to OUTPUT
 pinMode(aircore1SinDirPin1, OUTPUT);
 pinMode(aircore1SinDirPin2, OUTPUT);
 pinMode(aircore1CosDirPin1, OUTPUT);
 pinMode(aircore1CosDirPin2, OUTPUT);
}

void loop()                     
{
 //тестовая строка 
 //setMeterPosition(aircore1SinDirPin1, aircore1SinDirPin2, aircore1CosDirPin1, aircore1CosDirPin2, temp); 
 //вместо temp подбираются мин и макс значения типа float (приблизительно от -1.0 до 1.5) при которых стрелка устанавливается на крайние деления на датчике  
 dallRead(flagDallRead * 1000);
 delay(500); // не нужен в принципе
 //при использовании тестовых строк закомментировать 
 if (wTemp>=45.0) { //45 - первое деление на моем стрелочном датчике 
  wTemp = map(wTemp,45,135,-85,130); //т.к map не поддерживает тип float немного извратимся. Интервал от первого деления (то что не размечено) до последнего размеченного -0.85 1.3 
  setMeterPosition(aircore1SinDirPin1, aircore1SinDirPin2, aircore1CosDirPin1, aircore1CosDirPin2, wTemp/100); 
 }
 //при использовании тестовых строк закомментировать   
}

// setMeterPosition() - put it at the angle in radians
void setMeterPosition( int sinDirPin1, int sinDirPin2, int cosDirPin1, int cosDirPin2, float pos){

 // Calculate the voltage on the PWM pins based on the angle we want
 float sinCoilValue = maxAnalogRes*sin(pos);
 float cosCoilValue = maxAnalogRes*cos(pos);
 int sinn=0;
 int coss=0;
 if (sinCoilValue<=0) {
   sinn = 1;
 }
 if (cosCoilValue<=0) {
  coss = 1;}
 // take the absolute value because analogWrite doesn't take negatives
 sinCoilValue = abs(sinCoilValue);
 cosCoilValue = abs(cosCoilValue);
 // change the polarity of the coil depending on the sign of the voltage level
 if (sinn==1) {
   analogWrite(sinDirPin1, 0); //Change to LOW if using relays
   analogWrite(sinDirPin2, sinCoilValue); //comment this line out if using relays
 } else {
   analogWrite(sinDirPin1, sinCoilValue); //Change to HIGH if using relays
   analogWrite(sinDirPin2, 0); //comment this line out if using relays
 }
 if (coss==1) {
   analogWrite(cosDirPin1, 0); //Change to LOW if using relays
   analogWrite(cosDirPin2, cosCoilValue); //comment this line out if using relays
 } else {
   analogWrite(cosDirPin1, cosCoilValue); //Change to HIGH if using relays
   analogWrite(cosDirPin2, 0); //comment this line out if using relays
 }
}
//***Функция считывания температуры c Далласа*****
void dallRead(unsigned long interval) {
  static unsigned long prevTime = 0;
  if (millis() - prevTime > interval) { //Проверка заданного интервала
    static boolean flagDall = 0; //Признак операции
    prevTime = millis();
    flagDall = ! flagDall; //Инверсия признака
    if (flagDall) {
      ds.reset();
      ds.write(0xCC); //Обращение ко всем датчикам
      ds.write(0x44); //Команда на конвертацию
      flagDallRead = 1; //Время возврата в секундах
    }
    else {
        ds.reset();
        ds.select(addr);
        ds.write(0xBE); //Считывание значения с датчика
        wTemp = (ds.read() | ds.read() << 8); //Принимаем два байта температуры
        wTemp = (float)wTemp / 16.0;
        wTemp = wTemp - wTemp*0.02; // погрешность относительно тойотовского
        flagDallRead = 2; //Время возврата в секундах
    }
  }
}

 

bwn
Offline
Зарегистрирован: 25.08.2014

Если для начала закомментить все связанное с void setMeterPosition(), а значение wTemp вывести в сериал, тоже не работает?
И 93 строку тоже заккоментируйте, она меня смущает.))))

kitay-k
Offline
Зарегистрирован: 15.01.2017

Спасибо, что ответили.  Ситуация такая: если раскоментировать строку 30, начинает работать калибровка(максимальное или минимальное отклонение стрелки. Вашу подсказку попробую вечером, сейчас на работе

bwn
Offline
Зарегистрирован: 25.08.2014

Посмотрел еще раз, возможно проблема в 91 строке, в переменную типа float принимаете два байта. В оригинальной функции они принимались в локальную int temp;, а потом шел пересчет, и по какой то причине я этот int вводил.

kitay-k
Offline
Зарегистрирован: 15.01.2017

В общем  ничего не получается, знаний не хватает.

bwn
Offline
Зарегистрирован: 25.08.2014

Вот в таком виде, что выводит на экран. Скорость 9600 поставьте.

#include <OneWire.h>
OneWire  ds(2); // пин датчика температуры
byte addr[8]={0x28, 0xA0, 0xC7, 0x26, 0x00, 0x00, 0x80, 0xC4}; //адрес датчика температуры

//this is the maximum resolution of the PWM output.
//const int maxAnalogRes = 255;

//const int aircore1SinDirPin1 = 3;  //sin+ these two control the polarity to the "sine" coil
//const int aircore1SinDirPin2 = 5;  //sin-
//const int aircore1CosDirPin1 = 11; //cos+ these two control the polarity to the "cosine" coil
//const int aircore1CosDirPin2 = 6;  //cos-

float wTemp;
byte flagDallRead;

void setup()
{
 Serial.begin(9600);
  //TCCR2B = TCCR2B & 0b11111000 | 0x01;
 //TCCR0B = TCCR0B & 0b11111000 | 0x01;
 //Set the pins to OUTPUT
 //pinMode(aircore1SinDirPin1, OUTPUT);
 //pinMode(aircore1SinDirPin2, OUTPUT);
 //pinMode(aircore1CosDirPin1, OUTPUT);
 //pinMode(aircore1CosDirPin2, OUTPUT);
}

void loop()                     
{
 //тестовая строка 
 //setMeterPosition(aircore1SinDirPin1, aircore1SinDirPin2, aircore1CosDirPin1, aircore1CosDirPin2, temp); 
 //вместо temp подбираются мин и макс значения типа float (приблизительно от -1.0 до 1.5) при которых стрелка устанавливается на крайние деления на датчике  
 dallRead(flagDallRead * 1000);
 delay(500); // не нужен в принципе
 //при использовании тестовых строк закомментировать 
 //if (wTemp>=45.0) { //45 - первое деление на моем стрелочном датчике 
  //wTemp = map(wTemp,45,135,-85,130); //т.к map не поддерживает тип float немного извратимся. Интервал от первого деления (то что не размечено) до последнего размеченного -0.85 1.3 
  //setMeterPosition(aircore1SinDirPin1, aircore1SinDirPin2, aircore1CosDirPin1, aircore1CosDirPin2, wTemp/100); 
 //}
 //при использовании тестовых строк закомментировать   
}

// setMeterPosition() - put it at the angle in radians
//void setMeterPosition( int sinDirPin1, int sinDirPin2, int cosDirPin1, int cosDirPin2, float pos){

 // Calculate the voltage on the PWM pins based on the angle we want
 //float sinCoilValue = maxAnalogRes*sin(pos);
 //float cosCoilValue = maxAnalogRes*cos(pos);
 //int sinn=0;
 //int coss=0;
 //if (sinCoilValue<=0) {
   //sinn = 1;
 //}
 //if (cosCoilValue<=0) {
  //coss = 1;}
 // take the absolute value because analogWrite doesn't take negatives
 //sinCoilValue = abs(sinCoilValue);
 //cosCoilValue = abs(cosCoilValue);
 // change the polarity of the coil depending on the sign of the voltage level
 //if (sinn==1) {
   //analogWrite(sinDirPin1, 0); //Change to LOW if using relays
   //analogWrite(sinDirPin2, sinCoilValue); //comment this line out if using relays
 //} else {
   //analogWrite(sinDirPin1, sinCoilValue); //Change to HIGH if using relays
   //analogWrite(sinDirPin2, 0); //comment this line out if using relays
 //}
 //if (coss==1) {
   //analogWrite(cosDirPin1, 0); //Change to LOW if using relays
   //analogWrite(cosDirPin2, cosCoilValue); //comment this line out if using relays
 //} else {
   //analogWrite(cosDirPin1, cosCoilValue); //Change to HIGH if using relays
   //analogWrite(cosDirPin2, 0); //comment this line out if using relays
 //}
//}
//***Функция считывания температуры c Далласа*****
void dallRead(unsigned long interval) {
  static unsigned long prevTime = 0;
  if (millis() - prevTime > interval) { //Проверка заданного интервала
    static boolean flagDall = 0; //Признак операции
    prevTime = millis();
    flagDall = ! flagDall; //Инверсия признака
    if (flagDall) {
      ds.reset();
      ds.write(0xCC); //Обращение ко всем датчикам
      ds.write(0x44); //Команда на конвертацию
      flagDallRead = 1; //Время возврата в секундах
    }
    else {
        int temp;
         ds.reset();
        ds.select(addr);
        ds.write(0xBE); //Считывание значения с датчика
        temp = (ds.read() | ds.read() << 8); //Принимаем два байта температуры
        wTemp = (float)temp / 16.0;
        //wTemp = wTemp - wTemp*0.02; // погрешность относительно тойотовского
        flagDallRead = 2; //Время возврата в секундах
        Serial.println(wTemp);
    }
  }
}

P/S кстати, как узнали,что калибровка работает, если ничего никуда не выводите? ))))

kitay-k
Offline
Зарегистрирован: 15.01.2017

Попробую вечером, сейчас подрукой ничего нет.

Почему ничего не ввожу, если раскоментировать строку 30 и поставить вместо temp  значение от   -1,0 до 1,5,  активируется калибровка( максима

setMeterPosition(aircore1SinDirPin1, aircore1SinDirPin2, aircore1CosDirPin1, aircore1CosDirPin2,1);

льное или минимальное отклонение стрелки)

bwn
Offline
Зарегистрирован: 25.08.2014

Вы Serial.print возьмите на вооружение, без него отлаживать очень тяжело будет. Когда все переменные соответствут требуемым, тогда и испольнительные устройства можно прикручивать.

kitay-k
Offline
Зарегистрирован: 15.01.2017

попробывал залить, монитор порта отображает знаяение "-0.06", если отключить датчик "0.00". Получается, что неправильно организован опрос датчика?

bwn
Offline
Зарегистрирован: 25.08.2014

1-й пост, строка 003. Откуда брали значения адреса?

kitay-k
Offline
Зарегистрирован: 15.01.2017

честно говоря сам непойму, просто было много кусков кода,сейчас посмотрел адрес своего датчика он отличаеться, может быть в этом и дело?

 

bwn
Offline
Зарегистрирован: 25.08.2014

kitay-k пишет:

честно говоря сам непойму, просто было много кусков кода,сейчас посмотрел адрес своего датчика он отличаеться, может быть в этом и дело?

 

Вы когда письмо кому то пишете, адрес указываете или на "Деревню дедушке"?

kitay-k
Offline
Зарегистрирован: 15.01.2017

Сейчас попробую дописать, посмотрю что получиться.

kitay-k
Offline
Зарегистрирован: 15.01.2017

 Исправил адрес датчика, начал отображать температуру

bwn
Offline
Зарегистрирован: 25.08.2014

Ну вот, теперь убирайте комментарии со своих функций и смотрите как работает. Если что то не так, опять вставляем где нужно Serial и смотрим значение непонятной переменной.

kitay-k
Offline
Зарегистрирован: 15.01.2017

Спасибо огромное за разъясненияи подсказки!!!!!

bwn
Offline
Зарегистрирован: 25.08.2014

Не на чем, успехов на нелегком пути.))))

Андрей БАК
Offline
Зарегистрирован: 17.02.2015

Приветствую всех. Хочу подключить логомер к Arduino в точности как на этом видео.

https://youtu.be/ei9fWX3WZuU

Нужно управление стрелкой сигналом от 0 до 5 В.

Только логомер у меня немного другой, в нём есть небольшой редуктор.

сам мотор без редуктора:

https://sc01.alicdn.com/kf/HTB19stsawsSMeJjSsphq6xuJFXaV/Car-Stepper-Mot...

и вид стрелки : 

https://a.d-cd.net/2f7j5s-960.jpg

пишу с телефона Поэтому заранее извиняюсь если ссылки втыкнул неправильно.

Подскажите пожалуйста с чего начать чтобы написать программу или может быть есть какие-то готовые варианты скетча которые я могу использовать для себя.