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);
}
}