analogRead "ломает" ModBus

Shooa
Offline
Зарегистрирован: 18.02.2020
#include <ModbusRtu.h>

// assign the Arduino pin that must be connected to RE-DE RS485 transceiver
#define TXEN  17

uint16_t au16data[] = {0,0};

Modbus slave(1, Serial1, TXEN);

void setup() {
  Serial1.begin( 115200 ); // baud-rate at 115200
  slave.start();
}

void loop() {
  slave.poll(au16data, 2);
  au16data[REG_TEMPER] = analogRead(A0); // если эта строчка есть, то обмен по ModBus ломается
}

Всем привет.

Похоже, забуксовал на граблях:

Есть скетч, который использует ModBus. Его задача получить значение с определенного канала АЦП и положить в регистр ModBus. Сам Modbus работает безупречно, но лишь до первого использования функции analogRead. Значения читаются, но после этого слей не отвечает мастеру. Осцилла, к сожалению, под руками нет. Может быть есть какой-то очевидный косяк?

 

Shooa
Offline
Зарегистрирован: 18.02.2020

Arduino Micro, если это важно...

rkit
Offline
Зарегистрирован: 23.11.2016

Что за пин такой - 17?

REG_TEMPER откуда вылезло?

Shooa
Offline
Зарегистрирован: 18.02.2020

rkit пишет:

Что за пин такой - 17?

REG_TEMPER откуда вылезло?

 

Да я код пообрезал...

REG_TEMPER == 0, 17ый пин - кхм... 17ый порт... 

Оно работает... Но до того, как я вызываю analogRead.

rkit
Offline
Зарегистрирован: 23.11.2016

17й порт это еще хуже.

Shooa
Offline
Зарегистрирован: 18.02.2020

rkit пишет:

17й порт это еще хуже.

поменял, не помогло...

Shooa
Offline
Зарегистрирован: 18.02.2020
#include <ModbusRtu.h>

// assign the Arduino pin that must be connected to RE-DE RS485 transceiver
#define TXEN  5
#define PWM_1 3
#define PWM_2 4

#define FAN_POWER 8
#define FAN_SPEED_1 12 //9
#define FAN_SPEED_2 11 //10
#define FAN_SPEED_3 10 //11
#define FAN_SPEED_4 9 //12

#define DC_1 7
#define DC_2 6

#define GPIO_10 17
#define GPIO_2 2


enum Regs {
  REG_FAN_SPEED,
  REG_PWM_1_PERIOD,
  REG_PWM_1_DUTY,
  REG_PWM_2_PERIOD,
  REG_PWM_2_DUTY,
  REG_DRY_CON_1,
  REG_DRY_CON_2,
  REG_TEMPER,
  REG_GPIO_1,
  REG_GPIO_2,
  REG_SIZE
};

// FAN_SPEED, PERIOD_MS, DUTY,
uint16_t au16data[REG_SIZE];

Modbus slave(1, Serial1, TXEN);

void setup() {
  memset (au16data, 0, sizeof(au16data));

  pinMode(PWM_1, OUTPUT);
  digitalWrite(PWM_1, LOW);

  pinMode(PWM_2, OUTPUT);
  digitalWrite(PWM_2, LOW);

//  pinMode(GPIO_1, INPUT);
//  digitalWrite(GPIO_1, HIGH);

  pinMode(GPIO_2, INPUT);
  digitalWrite(GPIO_2, HIGH);

  pinMode(FAN_POWER, OUTPUT);

  pinMode(FAN_SPEED_1, OUTPUT);
  pinMode(FAN_SPEED_2, OUTPUT);
  pinMode(FAN_SPEED_3, OUTPUT);
  pinMode(FAN_SPEED_4, OUTPUT);

  pinMode(DC_1, OUTPUT);
  pinMode(DC_2, OUTPUT);

  Serial1.begin( 115200 ); // baud-rate at 115200
  Serial.begin( 115200 ); // baud-rate at 115200
  //  Serial.println(analogRead(A0));
  slave.start();
}

void processFanSpeed(uint16_t regime) {
  switch (regime) {
    case 1:
      digitalWrite(FAN_SPEED_1, HIGH);
      digitalWrite(FAN_SPEED_2, LOW);
      digitalWrite(FAN_SPEED_3, LOW);
      digitalWrite(FAN_SPEED_4, LOW);
      delay(10);
      digitalWrite(FAN_POWER, HIGH);
      break;
    case 2:
      digitalWrite(FAN_SPEED_1, LOW);
      digitalWrite(FAN_SPEED_2, HIGH);
      digitalWrite(FAN_SPEED_3, LOW);
      digitalWrite(FAN_SPEED_4, LOW);
      delay(10);
      digitalWrite(FAN_POWER, HIGH);
      break;
    case 3:
      digitalWrite(FAN_SPEED_1, LOW);
      digitalWrite(FAN_SPEED_2, LOW);
      digitalWrite(FAN_SPEED_3, HIGH);
      digitalWrite(FAN_SPEED_4, LOW);
      delay(10);
      digitalWrite(FAN_POWER, HIGH);
      break;
    case 4:
      digitalWrite(FAN_SPEED_1, LOW);
      digitalWrite(FAN_SPEED_2, LOW);
      digitalWrite(FAN_SPEED_3, LOW);
      digitalWrite(FAN_SPEED_4, HIGH);
      delay(10);
      digitalWrite(FAN_POWER, HIGH);
      break;
    default:
      digitalWrite(FAN_POWER, LOW);
      digitalWrite(FAN_SPEED_1, LOW);
      digitalWrite(FAN_SPEED_2, LOW);
      digitalWrite(FAN_SPEED_3, LOW);
      digitalWrite(FAN_SPEED_4, LOW);
      break;
  }
}

void processPwm_1(uint16_t *period, uint16_t *duty) {
  static int value = LOW;
  static long previousMillis = 0;

  if (*period > 300) {
    *period = 0;
    *duty = 0;
  }
  if (*duty > 100) {
    *period = 0;
    *duty = 0;
  }

  long _duty = *period * *duty * 10;
  long _period = *period * 1000;

  if (millis() - previousMillis < _duty)
    digitalWrite(PWM_1, HIGH);
  else
    digitalWrite(PWM_1, LOW);
  if (millis() - previousMillis > _period)
    previousMillis = millis();
}

void processPwm_2(uint16_t *period, uint16_t *duty) {
  static int value = LOW;
  static long previousMillis = 0;

  if (*period > 300) {
    *period = 0;
    *duty = 0;
  }
  if (*duty > 100) {
    *period = 0;
    *duty = 0;
  }

  long _duty = *period * *duty * 10;
  long _period = *period * 1000;

  if (millis() - previousMillis < _duty)
    digitalWrite(PWM_2, HIGH);
  else
    digitalWrite(PWM_2, LOW);
  if (millis() - previousMillis > _period)
    previousMillis = millis();
}

int16_t getTemp() {
  int16_t value = analogRead(0);
  //  Serial.println(value);
  return value;
}


void loop() {
  slave.poll(au16data, REG_SIZE);
  processFanSpeed(au16data[REG_FAN_SPEED]);
  processPwm_1(&(au16data[REG_PWM_1_PERIOD]), &(au16data[REG_PWM_1_DUTY]));
  processPwm_2(&(au16data[REG_PWM_2_PERIOD]), &(au16data[REG_PWM_2_DUTY]));
//  au16data[REG_GPIO_1] = digitalRead(GPIO_1);
  au16data[REG_GPIO_2] = digitalRead(GPIO_2);
//  au16data[REG_TEMPER] = getTemp();
  digitalWrite(DC_1, au16data[REG_DRY_CON_1]);
  digitalWrite(DC_2, au16data[REG_DRY_CON_2]);
}

Целиком...

rkit
Offline
Зарегистрирован: 23.11.2016

 

А с каких пор нулевой пин стал аналоговым?

Shooa
Offline
Зарегистрирован: 18.02.2020

rkit пишет:

 

А с каких пор нулевой пин стал аналоговым?

 

A0, конечно.

Shooa
Offline
Зарегистрирован: 18.02.2020

но это ничего не меняет.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Так "модбас ломается" только от analogRead в строке 176 или от любого, например в строке 164?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Если gettemp просто вызывать в лупе, но не сохранять в массиве.

Green
Offline
Зарегистрирован: 01.10.2015

rkit пишет:

А с каких пор нулевой пин стал аналоговым?

Да всю жизнь был! Как то слабовато, дядя. Зато одни понты.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Green пишет:

rkit пишет:

А с каких пор нулевой пин стал аналоговым?

Да всю жизнь был! 

Никада нулевой пин аналоговым не был. Был и есть четырнаццатый, он же A0.

Мы вещаем за то, что это 

164  int16_t value = analogRead(0);

неправильно

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DetSimen пишет:

Green пишет:

rkit пишет:

А с каких пор нулевой пин стал аналоговым?

Да всю жизнь был! 

Никада нулевой пин аналоговым не был. Был и есть четырнаццатый, он же A0.

Мы вещаем за то, что это 

164  int16_t value = analogRead(0);

неправильно

Ой ли!

int analogRead(uint8_t pin)
{
...
	if (pin >= 14) pin -= 14; // allow for channel or pin numbers

 

Green
Offline
Зарегистрирован: 01.10.2015

Дед, 0 - это не пин, а канал АЦП для analogRead. А0 == 0.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ну лана, ошибся я, ну дак я и не настаиваю, зачем я буду спорить с умными людями? :)   

Оправдываясь, ориентировался на ватэто, там нигде за 0 ничего не сказано, только за "A0 to A5 on most boards"

https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/

 

Shooa
Offline
Зарегистрирован: 18.02.2020

Вызов analogRead ломает модбас вне зависимости от аргументов и сохраняем ли мы возвращаемое значение или нет.
Если вызывать в setup - тоже самое.

nik182
Offline
Зарегистрирован: 04.05.2015
slave.start(); Это что за оператор? Что он делает? Здесь
всё замечательно работает  и ничего не ломается.  
 
Shooa
Offline
Зарегистрирован: 18.02.2020

Мой косяк. Причём аппаратный! Был коротыш между 3.3В и AREF.