Перейти к содержанию

Обнуляются millis и плывут значения переменных


Рекомендуемые сообщения

Всем привет. Столкнулся с такой проблемой: Пишу программу для устройства мониторинга оборотов двух валов используя датчик холла. Настроил прерывания,  перевод в RPM, все проверил, в .порт отправляются верные значения, и после настройки индикации столкнулся с проблемой неадекватного поведения переменных считающих millis, а после и индикации. В Arduino я не спец, Гляньте на код, может чем помогите. Заранее благодарен.

#include <EEPROM.h>
	#define CLOCK 13 //SH_CP
#define DATA 11  //DS
#define LATCH 10  //ST_CP
int numbers[5];
boolean ee = 0;
int mh;
int hh;
int et_mah;
int et_shl;
int ot_mah;
int ot_shl;
volatile  int rpm_mah = 0;
volatile  int rpm_shl = 0;
 int rpmmah_count = 0;
 int rpmshl_count = 0;
unsigned long lastmillis_mah = 0;
unsigned long lastmillis_shl = 0;
unsigned long lastmillis_show = 0;
unsigned char number[] =
{
  0b01111110, //0
  0b00110000, //1
  0b01101101, //2
  0b01111001, //3
  0b00110011, //4
  0b01011011, //5
  0b01011111, //6
  0b01110000, //7
  0b01111111, //8
  0b01111011, //9
  0b00000001, //-
  0b00000000  //тушим индикатор
};
	void setup() {
  Serial.begin(9600);
	  attachInterrupt(0, rpm_mahovik, FALLING);
  attachInterrupt(1, rpm_shluz, FALLING);
  pinMode(CLOCK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(LATCH, OUTPUT);
	}
	void rpm_mahovik() { /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
  rpmmah_count++;
}
void rpm_shluz() { /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
  rpmshl_count++;
}
	// чтение
//int EEPROM_int_read(int addr) {
//  byte raw[2];
 // for (byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr + i);
 // int &num = (int&)raw;
//  return num;
//}
	// запись
//void EEPROM_int_write(int addr, int num) {
//  byte raw[2];
 // (int&)raw = num;
 // for (byte i = 0; i < 2; i++) EEPROM.write(addr + i, raw[i]);
//}
	void show () {
  int x;
	
  for (x = 5; x >= 0; x--) {
   Serial.print("x= "); Serial.println(x);
    //включаем LATCH (Начинаем общение)
    digitalWrite(LATCH, LOW);
    shiftOut(DATA, CLOCK, LSBFIRST, number[numbers[x]]);
    //выключаем LATCH
    digitalWrite(LATCH, HIGH);
    //отключаем LATCH (чтобы регистр не ждал данных)
    digitalWrite(LATCH, HIGH);
  }
	}
//void ee_write () {
 // EEPROM_int_write(0, mh);
//  EEPROM_int_write(2, hh);
//  EEPROM_int_write(4, et_mah);
//  EEPROM_int_write(6, et_shl);
//  EEPROM_int_write(8, ot_mah);
//  EEPROM_int_write(10, ot_shl);
//}
	void loop() {
//  if ((millis() <= 100) & (ee == 0)) {
  //  mh = EEPROM_int_read(0);
 //   hh = EEPROM_int_read(2);
//    et_mah = EEPROM_int_read(4);
 //   et_shl = EEPROM_int_read(6);
 //   ot_mah = EEPROM_int_read(8);
 //   ot_shl = EEPROM_int_read(10);
 //   ee = 1;
 // }
	  if (millis() - lastmillis_mah == 1000) {
    detachInterrupt(0);
    rpm_mah = rpmmah_count * 60;
    rpmmah_count = 0;
    lastmillis_mah = millis();
    attachInterrupt(0, rpm_mahovik, FALLING);
  }
	  if (millis() - lastmillis_shl == 5000) {
    detachInterrupt(1);
    rpm_shl = rpmshl_count * 12;
    rpmshl_count = 0;
    lastmillis_shl = millis();
    attachInterrupt(1, rpm_shluz, FALLING);
  }
  if (millis() - lastmillis_show == 1000) {
    numbers[0] = rpm_mah / 1000;
    numbers[1] = (rpm_mah % 1000) / 100;
    numbers[2] = ((rpm_mah % 1000) % 100) / 10;
    numbers[3] = ((rpm_mah % 1000) % 100) % 10;
    numbers[4] = rpm_shl / 10;
    numbers[5] = rpm_shl % 10;
    lastmillis_show = millis();
  show();
Serial.print("RPM mah= "); Serial.println (rpm_mah); 
Serial.print("RPM shl= "); Serial.println (rpm_shl);  
Serial.print("Show millis= "); Serial.println(lastmillis_show);
Serial.print("Show mah= "); Serial.println(lastmillis_mah);
Serial.print("Show shl= "); Serial.println(lastmillis_shl);
  }
}

123.png

Изменено пользователем LukaS_St
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Пересоздал проект, ввел почти тот же код, почти все заработало корректно, но индикация через некоторое время останавливается (хотя микроконтроллер на кнопки реагирует). На железе индикация пропадает после 17 секунды, а в протеусе после 104.

#include <EEPROM.h>
#include <Bounce2.h>
	Bounce knopka_m = Bounce();
Bounce knopka_mah_plus = Bounce();
Bounce knopka_mah_minus = Bounce();
Bounce knopka_shl_plus = Bounce();
Bounce knopka_shl_minus = Bounce();
	#define CLOCK 13 //SH_CP
#define DATA 11  //DS
#define LATCH 10  //ST_CP
unsigned long lastmillis_show = 0;
byte numbers[] = {0, 0, 0, 0, 0, 0};
volatile int rpmmah_count = 0;
volatile int rpmshl_count = 0;
boolean ee = 0;
byte menu = 0;
int mh = 1234;
int hh = 0;
int et_mah = 900;
int et_shl = 80;
int ot_mah = 30;
int ot_shl = 3;
int rpm_mah = 0;
int rpm_shl = 0;
unsigned long lastmillis_mah = 0;
unsigned long lastmillis_shl = 0;
	unsigned char number[] =
{
  0b01111110, //0
  0b00110000, //1
  0b01101101, //2
  0b01111001, //3
  0b00110011, //4
  0b01011011, //5
  0b01011111, //6
  0b01110000, //7
  0b01111111, //8
  0b01111011, //9
  0b00000001, //-
  0b00000000  //тушим индикатор
};
	// чтение
int EEPROM_int_read(int addr) {
  byte raw[2];
  for (byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr + i);
  int &num = (int&)raw;
  return num;
}
	// запись
void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for (byte i = 0; i < 2; i++) EEPROM.write(addr + i, raw[i]);
}
	void ee_write () {
  EEPROM_int_write(0, mh);
  EEPROM_int_write(2, hh);
  EEPROM_int_write(4, et_mah);
  EEPROM_int_write(6, et_shl);
  EEPROM_int_write(8, ot_mah);
  EEPROM_int_write(10, ot_shl);
}
	void show() {
  int x;
  for (x = 5; x >= 0; x--) {
    //включаем LATCH (Начинаем общение)
    digitalWrite(LATCH, LOW);
    shiftOut(DATA, CLOCK, LSBFIRST, number[numbers[x]]);
    //отключаем LATCH (чтобы регистр не ждал данных)
    digitalWrite(LATCH, HIGH);
  }
}
	void rpm_mahovik() { /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
  rpmmah_count++;
}
void rpm_shluz() { /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
  rpmshl_count++;
}
	void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  attachInterrupt(0, rpm_mahovik, FALLING);
  attachInterrupt(1, rpm_shluz, FALLING);
	  pinMode(CLOCK, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(LATCH, OUTPUT);
  digitalWrite(LATCH, HIGH);
	  pinMode(19, INPUT_PULLUP);
  knopka_m.attach(19); // устанавливаем кнопку
  knopka_m.interval(5); // устанавливаем параметр stable interval = 5 мс
  pinMode(18, INPUT_PULLUP);
  knopka_mah_plus.attach(18); // устанавливаем кнопку
  knopka_mah_plus.interval(5); // устанавливаем параметр stable interval = 5 мс
  pinMode(17, INPUT_PULLUP);
  knopka_mah_minus.attach(17); // устанавливаем кнопку
  knopka_mah_minus.interval(5); // устанавливаем параметр stable interval = 5 мс
  pinMode(16, INPUT_PULLUP);
  knopka_shl_plus.attach(16); // устанавливаем кнопку
  knopka_shl_plus.interval(5); // устанавливаем параметр stable interval = 5 мс
  pinMode(15, INPUT_PULLUP);
  knopka_shl_minus.attach(15); // устанавливаем кнопку
  knopka_shl_minus.interval(5); // устанавливаем параметр stable interval = 5 мс
}
	void loop() {
  // put your main code here, to run repeatedly:
  if (EEPROM.read(0) == 0xFF) {
    ee_write ();
  }
	  if ((millis() <= 100) & (ee == 0)) {
    mh = EEPROM_int_read(0);
    hh = EEPROM_int_read(2);
    et_mah = EEPROM_int_read(4);
    et_shl = EEPROM_int_read(6);
    ot_mah = EEPROM_int_read(8);
    ot_shl = EEPROM_int_read(10);
    ee = 1;
  }
	  if (millis() - lastmillis_mah == 1000) {
    detachInterrupt(0);
    rpm_mah = rpmmah_count * 60;
    rpmmah_count = 0;
    lastmillis_mah = millis();
    attachInterrupt(0, rpm_mahovik, FALLING);
  }
	  if (millis() - lastmillis_shl == 5000) {
    detachInterrupt(1);
    rpm_shl = rpmshl_count * 12;
    rpmshl_count = 0;
    lastmillis_shl = millis();
    attachInterrupt(1, rpm_shluz, FALLING);
  }
	  if (millis() - lastmillis_show == 1000) {
    if (menu == 0) {
      numbers[0] = rpm_mah / 1000;
      numbers[1] = (rpm_mah % 1000) / 100;
      numbers[2] = ((rpm_mah % 1000) % 100) / 10;
      numbers[3] = ((rpm_mah % 1000) % 100) % 10;
      numbers[4] = rpm_shl / 10;
      numbers[5] = rpm_shl % 10;
    }
    if (menu == 1) {
      numbers[0] = mh / 1000;
      numbers[1] = (mh % 1000) / 100;
      numbers[2] = ((mh % 1000) % 100) / 10;
      numbers[3] = ((mh % 1000) % 100) % 10;
      numbers[4] = 11;
      numbers[5] = 11;
    }
    if (menu == 2) {
      numbers[0] = et_mah / 1000;
      numbers[1] = (et_mah % 1000) / 100;
      numbers[2] = ((et_mah % 1000) % 100) / 10;
      numbers[3] = ((et_mah % 1000) % 100) % 10;
      numbers[4] = et_shl / 10;
      numbers[5] = et_shl % 10;
    }
    if (menu == 3) {
      numbers[0] = ot_mah / 1000;
      numbers[1] = (ot_mah % 1000) / 100;
      numbers[2] = ((ot_mah % 1000) % 100) / 10;
      numbers[3] = ((ot_mah % 1000) % 100) % 10;
      numbers[4] = ot_shl / 10;
      numbers[5] = ot_shl % 10;
    }
    show();
    lastmillis_show = millis();
    Serial.println(lastmillis_show);
  }
  if (knopka_m.update() && knopka_m.read() == 0) {
    if (menu != 3) menu++;
    else {menu = 0; ee_write ();}
//  Serial.println ("Knopka");
  }
//////////////////////////////////////////////////////////////////
  if (knopka_mah_plus.update() && knopka_mah_plus.read() == 0) {
    if (menu == 2) {
      if (et_mah < 1000) et_mah = et_mah + 10;
    }
    if (menu == 3) {
      if (ot_mah < 100) ot_mah = ot_mah + 1;
    }
  }
  ////////////////////////////////////////////////////////////////////
  if (knopka_mah_minus.update() && knopka_mah_minus.read() == 0) {
    if (menu == 2) {
      if (et_mah > 800) et_mah = et_mah - 10;
    }
  }
  if (knopka_mah_minus.update() && knopka_mah_minus.read() == 0) {
    if (menu == 3) {
      if (ot_mah > 10) ot_mah = ot_mah - 1;
    }
  }
  /////////////////////////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////
  if (knopka_shl_plus.update() && knopka_shl_plus.read() == 0) {
    if (menu == 2) {
      if (et_shl < 70) et_shl = et_shl + 1;
    }
    if (menu == 3) {
      if (ot_shl < 20) ot_shl = ot_shl + 1;
    }
  }
  ////////////////////////////////////////////////////////////////////
  if (knopka_shl_minus.update() && knopka_shl_minus.read() == 0) {
    if (menu == 2) {
      if (et_shl > 30) et_shl = et_shl - 1;
    }
  }
  if (knopka_shl_minus.update() && knopka_shl_minus.read() == 0) {
    if (menu == 3) {
      if (ot_shl > 0) ot_shl = ot_shl - 1;
    }
}
}

123.png

Изменено пользователем LukaS_St
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

20 минут назад, LukaS_St сказал:

if (millis() - lastmillis_mah == 1000) {     detachInterrupt(0);     rpm_mah = rpmmah_count * 60;

кто сказал что это условие будет выполнятся всегда?

Если бы мс инкрементировали в этом же цикле, такое условие допустимо

правильно писать

if (millis() - lastmillis_mah) >= 1000)

{

}

 

Изменено пользователем hasl
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Пробовал и так писать. Из трех таких условий перестает только одно работать( Ликвидировал эту проблему объединив 2 части кода в одно условие, что привело к отсутствию  возможности регулировки частоты вывода информации на индикаторы.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...