#1 2018-06-23 20:13:28

Segmalion
Учасник
Зареєстрований: 2018-06-23
Повідомлень: 3

Oled дисплей не работает с attachInterrupt (Спидометр на велик)

Попытался сделать спидометр на датчеке хола и OLED дисплее. Написал кодик:

#include <OLED_I2C.h>

OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];

unsigned long lastturn, time_press; //переменные хранения времени
float SPEED; //переменная хранения скорости в виде десятичной дроби
float DIST; //переменная хранения расстояния в виде десятичной дроби
float w_length=2.080; //длина окружности колеса в метрах
unsigned long count=0;

void setup(){
  myOLED.begin();
  myOLED.setFont(MediumNumbers);
  Serial.begin(9600);
  attachInterrupt(0,sens,RISING);//interrupt cero (0) is on pin two(2).
}

void sens(){
  if (millis()-lastturn > 80) {  //защита от случайных измерений
    SPEED=w_length/((float)(millis()-lastturn)/1000)*3.6;  //расчет скорости, км/ч
    lastturn=millis();  //запомнить время последнего оборота
    DIST=DIST+w_length/1000;  //прибавляем длину колеса к дистанции при каждом обороте оного
    count++;
  }
}

void loop(){
  myOLED.setFont(MediumNumbers);
  myOLED.printNumI(count, RIGHT, 0);
  Serial.println(count);
  delay(1000);
}

Для проверки вывожу только количество срабатываний датчика хола в монитор порта и на экран. Но заметил проблему экран не работает при активном attachInterrupt. По отдельности все работает...
В чем может быть проблема?

Остання редакція Segmalion (2018-06-23 20:14:08)

Неактивний

#2 2018-06-23 20:30:37

Kaka
Учасник
Зареєстрований: 2018-03-21
Повідомлень: 411

Re: Oled дисплей не работает с attachInterrupt (Спидометр на велик)

I2C ломается.

Сделай так:

опиши глобальную переменную

volatile interruptFlag = false;

в функции sense напиши только

interruptFlag = true;

и больше ничего.

А в loop вставь (хоть в начало, хоть в конец) такую байду

if (interruptFlag) {
     interruptFlag = false;
     .....
}

Вместо многоточия вставь ВСЮ бодягу, которая у тебя сейчас находится в sens.

Должно заработать.

Неактивний

#3 2018-06-23 20:48:29

Segmalion
Учасник
Зареєстрований: 2018-06-23
Повідомлень: 3

Re: Oled дисплей не работает с attachInterrupt (Спидометр на велик)

Не помогло, теперь счетчик без срабатывания датчика растет.. Дисплей все также не пашет

Неактивний

#4 2018-06-23 21:27:10

Вячеслав Азаров
Учасник
Зареєстрований: 2017-05-25
Повідомлень: 1,732

Re: Oled дисплей не работает с attachInterrupt (Спидометр на велик)

Примените библиотеку графики U8g2. Она получше.

Неактивний

#5 2018-06-24 12:37:24

Segmalion
Учасник
Зареєстрований: 2018-06-23
Повідомлень: 3

Re: Oled дисплей не работает с attachInterrupt (Спидометр на велик)

Вячеслав Азаров пише:

Примените библиотеку графики U8g2. Она получше.

Спасибо, все получилось. Вот если кому надо код:

#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

U8G2_SSD1306_128X64_NONAME_1_SW_I2C u8g2(U8G2_R0,SCL,SDA,U8X8_PIN_NONE);

unsigned long lastturn, time_press;   //переменные хранения времени
float SPEED;    //переменная хранения скорости в виде десятичной дроби
float DIST;     //переменная хранения расстояния в виде десятичной дроби
float w_length=2.080;     //длина окружности колеса в метрах
unsigned long count=0;
char bufSpeed[16], bufDist[16], bufCount[16];


void setup(){
  u8g2.begin(); 
  Serial.begin(9600);
  attachInterrupt(0,sens,RISING); //иницилизация прерываний
}

void sens(){
  //if (millis()-lastturn > 10) {   //защита от случайных измерений
    SPEED=w_length/((float)(millis()-lastturn)/1000)*3.6;   //расчет скорости, км/ч
    lastturn=millis();     //запомнить время последнего оборота
    DIST=DIST+w_length/1000;      //прибавляем длину колеса к дистанции при каждом обороте оного
    count++;
    updateScreen();
  //}
}

void loop(){
  Serial.println(count);
  delay(1000);
}

void draw(){
  u8g2.setFont(u8g_font_courB24);
  u8g2.drawStr( 36, 45, bufCount);
}

void updateScreen(){
  sprintf(bufCount,"%d",count);
  u8g2.firstPage();
  do {
    draw();
  } while( u8g2.nextPage() );
  
}

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму