Подскажите как лучше сделать денаминеское смещение курсора

mixan
Offline
Зарегистрирован: 03.09.2015

Доброго времени суток!

Прошу не пинайте сильно, я новичёк в программировании.

Делаю для себя часы - термометр на 16*2 I2C дисплее, реалтайме DS3231, датчиках температуры ds1820. Датчиков температуры 2шт.

Основные задачи: понять что и как рпботает, разобраться в программировании.

Подскажите как лучше сделать денаминеское смещение курсора в строках 134, 135, 138, 141

#include <Wire.h>                 //библиотека для работы с I2C
#include <OneWire.h>              //библиотека для работы с DS18x20
#include <Sodaq_DS3231.h>         //библтотека для работы с DS3231 RTC 0x68
#include <LiquidCrystal_I2C.h>    //библиотека для работы с I2C дисплеем
LiquidCrystal_I2C lcd(0x3F, 16, 2);//инициализация I2C дисплея по адресу 0x3F на 16 символов 2 строки

int ul = 11;
int hom = 12;
int iz_term = 0;

float ds18x20(int term){
  OneWire ds(term);               //указываем порт к которому подключен DS18x20
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius;

  if ( !ds.search(addr)) {
    ds.reset_search();
    delay(50);
  }
  switch (addr[0]) {        // the first ROM byte indicates which chip
    case 0x10:
      type_s = 1;
      break;
    case 0x28:
      type_s = 0;
      break;
    case 0x22:
      type_s = 0;
      break;}

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  delay(750);     // maybe 750ms is enough, maybe not
  present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);         // Read Scratchpad
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
  }
  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  //fahrenheit = celsius * 1.8 + 32.0;
  iz_term = 1;
  return celsius;
}

void lcd_print_char(int lcd_str, int lcd_smb, char char_data){
  lcd.setCursor(lcd_smb, lcd_str);
  lcd.write(char_data);
}
void lcd_print_int(int lcd_str, int lcd_smb, int int_data){
  lcd.setCursor(lcd_smb, lcd_str);
  lcd.print(int_data);
}
void lcd_print_float(int lcd_str, int lcd_smb, float float_data){
  lcd.setCursor(lcd_smb, lcd_str);
  lcd.print(float_data);
}
void lcd_simbols(){
  
  lcd_print_char(0, 2, ':');        //печатаем ':'
  lcd_print_char(0, 5, ':');
  lcd_print_char(0, 15, 223);
  lcd_print_char(1, 15, 223);       //печатаем знак градуса
  lcd_print_char(1, 2, '.');
  lcd_print_char(1, 5, '.');
}


void setup() {
  Serial.begin(230400);
  Wire.begin();
  rtc.begin();                    // инициализация RTC
  lcd.init();                     // инициализация LCD
  lcd.backlight();                // включаем подсветку
  lcd.clear();                    // очистка дисплея
  lcd_simbols();
}

void loop() {
  
  DateTime now = rtc.now();         //получение текущих даты и времени
  if(now.hour() < 10){
    lcd_print_char(0, 0, '0');
    lcd_print_int(0, 1, now.hour());
  }else{
  lcd_print_int(0, 0, now.hour());}
  if(now.minute() < 10){
    lcd_print_char(0, 3, '0');
    lcd_print_int(0, 4, now.minute());
  }else{
  lcd_print_int(0, 3, now.minute());}
  if(now.second() < 10){
    lcd_print_char(0, 6, '0');
    lcd_print_int(0, 7, now.second());
  }else{
  lcd_print_int(0, 6, now.second());}
  if(now.date() < 10){
    lcd_print_char(1, 0, '0');
    lcd_print_int(1, 1, now.date());
  }else{
  lcd_print_int(1, 0, now.date());}
  if(now.month() < 10){
    lcd_print_char(1, 3, '0');
    lcd_print_int(1, 4, now.month());
  }else{
  lcd_print_int(1, 3, now.month());}
  lcd_print_int(1, 6, now.year()-2000);
  int last = now.minute();
  if(iz_term == 0){
    lcd_print_float(0, 10, ds18x20(hom));
    lcd_print_float(1, 10, ds18x20(ul));
  }
  if(last+2 == now.minute()){
    lcd_print_float(0, 10, ds18x20(hom));
  }
  if(last+5 == now.minute()){
    lcd_print_float(1, 10, ds18x20(ul));
  }
}

Есть одна идея: полуить кол-во символов содержащихся в переменной celsius, потом отнять это число от 15 (последний символ градус), и записать значение как позицию курсора. Но есть одна проблема в этой идеи, я не нашёл способов получения кол-ва символов из переменной.

Может кто подскажет как это сделать.

mixan
Offline
Зарегистрирован: 03.09.2015

Сори, код плохо прокоментирован.

Radjah
Offline
Зарегистрирован: 06.08.2014

http://playground.arduino.cc/Main/Printf

DateTime now = rtc.now();
DateTime MSK (now + 3 * 3600);
char dt[18] = "";
sprintf(dt, "%04d/%02d/%02d %02d:%02d:%02d", MSK.year(),
                                             MSK.month(),
                                             MSK.day(),
                                             MSK.hour(),
                                             MSK.minute(),
                                             MSK.second());

lcd.setCursor(0, 0);
lcd.print(dt);

Так проще ;)

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

mixan пишет:

Есть одна идея: полуить кол-во символов содержащихся в переменной celsius, потом отнять это число от 15 (последний символ градус), и записать значение как позицию курсора. Но есть одна проблема в этой идеи, я не нашёл способов получения кол-ва символов из переменной.

Может кто подскажет как это сделать.

Это невозможно. Ученые с мировыми именами до сих спорят сколько знаков может быть у числа в интервале от 10 до 99. Я уже молчу про количство знаков после запятой... Это я еще отрицательными значениями не пугал.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

mixan пишет:

Есть одна идея: полуить кол-во символов содержащихся в переменной celsius, потом отнять это число от 15 (последний символ градус), и записать значение как позицию курсора. Но есть одна проблема в этой идеи, я не нашёл способов получения кол-ва символов из переменной.

В этой переменной ввобще не содержится никаких символов, т.к. она имеет тип float. Сначала преобразуйте её в строку, а уж в строке считайте символы функцией strlen.