I2C и отключение прерываний noInterrupts()
- Войдите на сайт для отправки комментариев
Вс, 25/01/2015 - 21:59
#include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27,16,2); #define FASTADC 1 // defines for setting and clearing register bits #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif //для пищалки //#define R3_PIN A0 #define SPEAKER_PIN 11 #define T2_WGM 0b010 #define T2_COMA 0b01 #define T2_CS 0b111 // параметры подстройки int pMID=0; int pMAX=0; int pMIN=0; int Sensv = 0; //(0 - макс чувствительность, минимум - около сотни наверное.) int LastData[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; int SetupData[200]; void delayms(int ms) { for (int i=0;i<ms;i++) delayMicroseconds(1000); } void setup() { //set port/pin mode //DDRD = 0xFF;//all outputs //DDRC = 0x0F;//all inputs //DDRD = 0xFF;//all outputs //DDRC = B11111110; //TIMER INTERRUPT SETUP DDRD = DDRD | B00001110; PORTD = B00001110; //PORTD = 0; lcd.init(); lcd.backlight(); lcd.print("START "); #if FASTADC // set prescale to 16 sbi(ADCSRA,ADPS2) ; cbi(ADCSRA,ADPS1) ; cbi(ADCSRA,ADPS0) ; #endif //для динамика TCCR2A = (T2_COMA << 6) | (T2_WGM & 0b011); TCCR2B = ((T2_WGM & 0b100) << 1) | T2_CS; OCR2A = 18; // pinMode(R3_PIN, INPUT); // pinMode(SPEAKER_PIN, INPUT); // pinMode(SPEAKER_PIN, OUTPUT); noInterrupts(); beep(100); delayms(100); beep(100); delayms(100); beep(100); delayms(1000); //посылаем пару тыщ импульсов в холостую просто так // lcd.clear(); lcd.setCursor(0,0); lcd.print("SETUP... "); //while (1) for (int i=0;i<200;i++) { int t = SendPulse(); delayMicroseconds(6500); } //посылаем 200 импульсов для настройки for (int i=0;i<200;i++) { int t = SendPulse(); SetupData[i]=t; delayMicroseconds(6500); } int tmin=1024; int tmax=0; unsigned long tnak=0; for (int i=0;i<200;i++) { tnak=tnak+SetupData[i]; if (SetupData[i]>tmax) tmax = SetupData[i]; if (SetupData[i]<tmin) tmin = SetupData[i]; } pMID = tnak/200; pMIN = tmin; pMAX = tmax; lcd.clear(); lcd.setCursor(0,1); lcd.print(pMIN); lcd.setCursor(5,1); lcd.print(pMID); lcd.setCursor(10,1); lcd.print(pMAX); /* //for test for (int i=0;i<200;i++){ lcd.setCursor(0,0); lcd.print(SetupData[i]); delayms(1000); lcd.setCursor(0,0); lcd.print(" "); }*/ beep(500); } //Функция опроса кнопок модуля дисплея 1602 с кнопками. //кнопки подключены к аналоговому порту (0) ардуино, если их подключаете как то иначе - функцию необходимо переделать int getKey() { int value = analogRead(0); if (value>1000) return 0; //ничего не нажато if (value>580) return 1; //SELECT //Автонастройка. if (value>380) return 2; //ЛЕВО if (value>200) return 3; //ВНИЗ //Уменьшить порог (увеличивается чувствительность) if (value>80) return 4; //ВВЕРХ //Увеличить порог (снижается чувствительность) if (value<50) return 5; //ВПРАВО } void beepOn() { pinMode(SPEAKER_PIN, OUTPUT); } void beepOff() { pinMode(SPEAKER_PIN, INPUT); } void beep(int msec) { beepOn(); delayms(msec); beepOff(); } int lmax = 10; int mmax = 80; int mmaxDefault = 80; int lmaxDefault = 10; int LL=lmax; //Длина звук. сигнала, циклов int MM=mmax; //Длина тишины, циклов. int vo = 0; int vi = 0; int vod = 0; int vid = 0; unsigned long v1 = 0; int SendPulse() { //-------------------------- //Начало импульса //Мощный ключ открыт, усилитель выключен. PORTD = B00000010; //------------------------- //Ожидаем 100мкс: delayMicroseconds(100); //Закрываем ключ: PORTD = B00001010; //Открываем Q1: delayMicroseconds(12); //Защитный интервал PORTD = B00001110; delayMicroseconds(7); PORTD = B00001100; delayMicroseconds(100); PORTD = B00001110; int r = analogRead(1); return r; } int tControl = 0; //может изменяться от 0 до 15 int maxControl = 10; //кол-во измерений для расчета - чем больше количество измерений, тем меньше влияние шума. //При тестировании в доме я выставлял 12-15 измерений для получения стабильной работы. //В поле достаточно двух int getMidControl() { int gm = 0; for (int i=0;i<maxControl;i++) { gm = gm+LastData[i]; } int res = gm/maxControl; return res; } char Str2[11] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,'\0'}; int V; void(* resetFunc) (void) = 0; //сброс int setupcount = 150; void loop() { int k =0; //tone(SPEAKER_PIN,400); noInterrupts(); //lcd.setCursor(0,0); //lcd.print(t); //Бит 3 = 1, J3 //Бит 2 = 1 J4 //Бит 1 = 1, J9 PORTD = B00001110; delayms(2000); int ssl=0; lcd.clear(); lcd.setCursor(0,0); lcd.print(" "); lcd.setCursor(12,1); lcd.print(" "); lcd.setCursor(12,1); lcd.print(Sensv); int a = 0; int val; LL=9; while (1) { k = getKey(); if(tControl>=maxControl) tControl=0; int t = SendPulse(); LastData[tControl] = t; int s = getMidControl(); tControl++; //для тестирования //pMID = 781; //s = 520; //================== //================================== // ОЗВУЧКА ЦЕЛИ V //================================== if (LL<lmax && LL>0) LL--; if (LL==0 && MM>0) MM--; if (MM==0) { LL = lmax; MM = mmax; } if (setupcount>0) { if (s<=pMID) pMID = pMID-1; setupcount--; } int signal=(pMID-Sensv)-s; //для средних значений //int signal=(pMIN-Sensv)-s; //для минимальных if (signal>0 && LL==lmax) { beepOn(); //if (signal<50) slevel = 2- int slevel = 200-signal; //цифра влияет на чувствительность пищалки. 400- редко пикает, затем часто до писка. 50 - быстро, затем писк. if (slevel<5) slevel = 5; mmax = slevel/5; MM = mmax; LL--; } if (signal<0 && LL==lmax) { mmax = mmaxDefault; MM = mmax; } int ssk = signal; signal = signal/5; if (signal<0) signal = 0; for (int i=0;i<10;i++) { if (i<signal) Str2[i] = 0xff; else Str2[i] = ' '; } if (LL==0) beepOff(); //================================== //================================== //if (a==0) val = s; lcd.setCursor(0,1); lcd.print(Str2); a++; if (k==4) { Sensv++; lcd.setCursor(12,1); lcd.print(" "); lcd.setCursor(12,1); lcd.print(Sensv); beep(100); delayms(100); } if (k==3) { Sensv--; lcd.setCursor(12,1); lcd.print(" "); lcd.setCursor(12,1); lcd.print(Sensv); beep(100); delayms(100); } if (k==1) { pMID = t; Sensv = 0; setupcount = 150; lcd.setCursor(12,1); lcd.print(" "); lcd.setCursor(12,1); lcd.print(Sensv); beep(200); delayms(500); //resetFunc(); }; delayMicroseconds(1000); lcd.setCursor(0,0); lcd.print(vi); lcd.print('.'); lcd.print(vid); lcd.print("V "); lcd.print(ssl); lcd.print(' '); if (a>200) { a = 0; //1 раз за 200 циклов измеряем напряжение аккумулятора и выводим на экран V = analogRead(4); //V = V-73; //калибровка во вольтметру unsigned long vt = V*125l; vt = vt/64l-140; vi = vt/100; vid = vt/10%10; ssl = ssk/10; //vi = v1*4; } //lcd.print(vid); //lcd.print(vi); } }