Тахометр на прерываниях
- Войдите на сайт для отправки комментариев
Пт, 14/04/2017 - 09:50
Делаю тахометр. Столкнулся с проблеммой непонятных ипульсов по порту прерывания.
1 Ардуинка UNO выполняет роль генератора импульсов.
По сериалу выводил время включения выключения порта. вроде тут все правильно. но на всякий случай код.
unsigned long int time; //unsigned long int time2; float wait, oborots; void setup() { pinMode(13, OUTPUT); time = millis(); Serial.begin (9600); oborots = 800; wait = (1000000 / (oborots / 60)); } void loop() { if ((micros() - time) > (wait)) { digitalWrite (13, HIGH); time = micros(); digitalWrite (13, LOW); } }
2 Ардуина мега. прерывание 4 (19 порт). подключен tft экран 2.4, поэтому кода больше чем надо для тахо.
#include <OneWire.h> // библиотека связи с датчиком температуры #include <DallasTemperature.h> // библиотека датика температры #include <TouchScreen.h> //Библиотека сенсорного экрана #include <Adafruit_GFX.h>// подключаем библотеку экрана #include <gfxfont.h>// фонт для вывода #include <MCUFRIEND_kbv.h> // драйвер экрана #include <SD.h> //Библиотека SD карты #include <SPI.h> // Библиотека SPI для SD карты #define LCD_RD A0 //для LCD #define LCD_WR A1 //и для LCD и для сенсора #define LCD_RS A2 //и для LCD и для сенсора #define LCD_CS A3 //для LCD #define BLACK 0x0000 #define BLUE 0x001A #define RED 0xFBEF #define GREEN 0x07E0 //#define CYAN 0x33FF #define CYAN 0xDDFF #define MAGENTA 0xF81F #define YELLOW 0xFFE0 #define WHITE 0xFFFF #define YM 7 // для сенсора #define XP 6 // для сенсора 28FF93107216038D int pinTemp = 48;//порт подключения датчика температур int temppres = 1; //SD CARD //SD_SS=CS=10 SD_DI=MOSI=11 SD_DO=MISO=12 SD_SCK=CLK=13 #define SD_CS 53 //пин картридера File myFile; uint8_t G = 0x0000; // данные чтения с карты uint8_t B = 0x0000; // данные чтения с карты //pinMode(53, OUTPUT); MCUFRIEND_kbv tft; OneWire oneWire(pinTemp);//библиотека для температуры DallasTemperature tempsens(&oneWire); ;//библиотека для температуры DeviceAddress term1 = {0x28, 0xFF, 0x93, 0x10, 0x72, 0x16, 0x03, 0x8D}; // адрес датчика температуры 28FF93107216038D volatile unsigned long int time = 0; //для учета оборотов volatile unsigned long int time_last = 0;//для учета оборотов volatile unsigned long int rpm_array[5] = {0, 0, 0, 0, 0};//для учета оборотов volatile unsigned long int rpm;//для учета оборотов int unsigned long time_screen;//для ограничения вывода на экран float x1, y1, x2, y2, h; //для вывода тахометра по кругу int clockCenterX = 319; //для вывода тахометра по кругу int clockCenterY = 239; //для вывода тахометра по кругу int x3, y3, x4, y4;//для вывода тахометра по кругу TouchScreen ts = TouchScreen(XP, LCD_RS, LCD_WR, YM, 269);// TouchScreen ts = TouchScreen(XP, YP, XM, YM, 269); short TS_MINX = 20; //для сенсора short TS_MINY = 20;//для сенсора short TS_MAXX = 920;//для сенсора short TS_MAXY = 940;//для сенсора int Y, X;//для сенсора int temp1; // для температуры int tipvivoda = 1; // флаг для переключения типа отображения; void setup() { pinMode(19, INPUT); tempsens.begin(); //инициализация датчиков температуры tempsens.setResolution(term1, temppres);// установка разрешающую способности датчика tft.reset(); tft.cp437(true); uint16_t identifier = tft.readID(); tft.begin(identifier); tft.setRotation(1); tft.fillScreen(BLACK); tft.setTextSize(5); Serial.begin(9600); time_screen = millis(); if (!SD.begin(53)) { Serial.println("initialization failed!"); return; } /*SD.begin(SD_CS); // включаем картриер X = 0; Y = 0; delay(100); myFile = SD.open("1.bmp", FILE_READ); //рисуем кнопку настройки if (!myFile) { Serial.println("file opening faled"); } delay(100); knopki();*/ if (tipvivoda == 1) { riski(); //рисуем черточки и цифры } attachInterrupt(4, merilka, FALLING); } void loop() { if ((millis() - time_screen ) > 100) { tempsens.requestTemperatures(); //опрос датчиков температуры temp1 = tempsens.getTempC(term1); //получение данных tft.setCursor(190, 190); tft.setTextColor(CYAN , BLACK); tft.setTextSize(6); if (temp1 > -1) { tft.print ("+"); tft.print (temp1); } else { tft.print (temp1); } } if ((millis() - time_screen ) > 100) { if (tipvivoda == 0) { printscreen(); time_screen = millis(); } else { drawscreen(((rpm - 600) / 100)); time_screen = millis(); } } sensor(); if ((X > 0) && (Y > 0)) { //detachInterrupt(4); if (tipvivoda == 0) { tipvivoda = 1; tft.fillScreen(BLACK); riski(); } else { tipvivoda = 0; tft.fillScreen(BLACK); tft.setTextSize(5); } // attachInterrupt(5, merilka, RISING); } } void merilka () { //измеряем обороты detachInterrupt(4); time = (micros() - time_last); time_last = micros(); rpm_array[0] = rpm_array[1]; rpm_array[1] = rpm_array[2]; rpm_array[2] = rpm_array[3]; rpm_array[3] = rpm_array[4]; rpm = (60 * (1000000 / (time))) / 100; rpm_array[4] = rpm * 100 ; rpm = (rpm_array[0] + rpm_array[1] + rpm_array[2] + rpm_array[3] + rpm_array[4]) / 5; Serial.println(time); attachInterrupt(4, merilka, FALLING); } void printscreen() { // выводим цифрами // detachInterrupt(4); tft.setCursor(0, 0); tft.setTextColor(CYAN , BLACK); tft.print (rpm); tft.print (" "); //Serial.println(time); // attachInterrupt(5, merilka, RISING); } void drawscreen(int h) { //выводим стрелкой tft.fillTriangle(x1, y1, x2 - 4, y2 + 4, x2 + 4, y2 - 4, BLACK); h = h * 2; h = h + 180; x1 = 210 * cos(h * 0.0175); y1 = 210 * sin(h * 0.0175); x2 = 180 * cos(h * 0.0175); y2 = 180 * sin(h * 0.0175); x3 = (x1 + clockCenterX); y3 = (y1 + clockCenterY); x4 = (x2 + clockCenterX); y4 = (y2 + clockCenterY); tft.fillTriangle(x3, y3, x4 - 4, y4 + 4, x4 + 4, y4 - 4, CYAN); x1 = x3; x2 = x4; y1 = y3; y2 = y4; } void riski() { //рисуем циферблат tft.drawCircle(319, 239, 172, CYAN); tft.drawCircle(319, 239, 211, CYAN); for (float n = 0; n < 5; n++) { for (float i = -1; i < 2; i) { h = 183 + i * 0.25 + n * 20; x1 = 220 * cos(h * 0.0175); y1 = 220 * sin(h * 0.0175); x2 = 210 * cos(h * 0.0175); y2 = 210 * sin(h * 0.0175); x3 = (x1 + clockCenterX); y3 = (y1 + clockCenterY); x4 = (x2 + clockCenterX); y4 = (y2 + clockCenterY); tft.drawLine(x3, y3, x4, y4 , CYAN); i = i + 1; } } tft.setCursor(85, 215); tft.setTextColor(CYAN ); tft.setTextSize(3); tft.print (1); tft.setCursor(98, 137); tft.print (2); tft.setCursor(140, 72); tft.print (3); tft.setCursor(203, 25); tft.print (4); tft.setCursor(300, 0); tft.print (5); tft.setCursor(180, 160); tft.setTextColor(CYAN , BLACK); tft.setTextSize(2); tft.print (utf8rus("Температура")); tft.setCursor(192, 175); tft.print (utf8rus("за бортом")); } String utf8rus(String source) { int i, k; String target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x30; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB8; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x70; break; } } } m[0] = n; target = target + String(m); } return target; } void sensor(void) // опрос сенсора экрана { TSPoint tem = ts.getPoint(); X = 0; Y = 0; pinMode(LCD_WR, OUTPUT);// для сенсорного экрана pinMode(LCD_RS, OUTPUT);// для сенсорного экрана if (tem.z > 0) { Y = (map(tem.x, TS_MINX, TS_MAXX, tft.height(), 0)); X = (map(tem.y, TS_MINY, TS_MAXY, tft.width(), 0)); X = X - 14; Y = Y - 14; if (X < 0) { X = 0; } if (Y < 0) { Y = 0; } X = X * 1.172; Y = Y * 1.23; if (X > 320) { X = 320; } if (Y > 240) { Y = 240; } //tft.drawFastHLine(X,Y,2,RED); } } void knopki() { //функция чтения с карты и вывода на экран for (int tem1 = 0; tem1 <= 53; tem1++) { B = myFile.read(); } for (int tem1 = 0; tem1 <= 11; tem1++) { B = myFile.read(); } for (int Y1 = 240; Y1 > 0; Y1--) { for (int X1 = 320; X1 > 0; X1--) { B = myFile.read(); G = myFile.read(); tft.drawPixel(320 - X1 + X, Y1 + Y - 1, G * 256 + B); } } myFile.close(); }
Замер времени между ипульсами показывает
Подключение : выходной пор UNO посажен напрямую на 19 порт MEGA. Также пробовал через резистор подтягивать на землю. Результат не меняется...
Уже хз куда копать.
Причем пару дней назад работало ... в какой то момент перестало. Пробовал менять порт на которое идет прерывание. Все тоже самое.
Если просто убрать сигнал с 19 порта меги то прерывание не срабатывает.
Так же за место UNO в качестве генератора использовал модуль на NE555. Все тоже самое.
Вешал на выход генератора светодиодик... моргает быстро. Осцилографа чтобы померить нет.
Хм переношу куски кода в пустой скетч и все работает ...
Поймал... глюки начинаются при опросе датчика ds18b20. Счем связано?
Библиотеки ONEWIRE и DallasTemperature
Наверное потому что по OneWire щедро накидано noInterrupts(); ... interrupts();
ясно ... решил что температура будет обновляться раз в 10 минут ... и забил ) 1 проскок левых данных ничего страшного