Отключение i2c после нескольких прерываний.
- Войдите на сайт для отправки комментариев
Пнд, 13/06/2016 - 20:22
Здравствуйте уважаемые форумчане.
По прерыванию я считаю импульсы, потом количество импульсов по таймеру сбрасываю, импульсы насчитанные за секунду передаю по i2c (вместе с еще парой тестовых параметров). Вместе с этим генерируется ШИМ . Сначала от внешнего устройства приходит число 7, ардуинка начинает генерировать ШИМ и посылать на устройство насчитанное кол-во импульсов и еще некоторые тестовые данные. По непонятной мне причине спустя 5-6 пересылок i2c перестает принимать и получать данные. Почему?
#include <Wire.h> #include <TimerOne.h> #define SLAVE_ADDRESS 0x04 int mode = 0; int pwd_freq=0; int ledPin = 13; int writePWMpin = 9; unsigned int onSecondImpulsCounter=0,onSecondImpulsSend=0; void setup() { pinMode(ledPin, OUTPUT); Serial.begin(9600); Wire.begin(SLAVE_ADDRESS); pinMode(writePWMpin, OUTPUT); Wire.onReceive(receiveData); Wire.onRequest(sendData); // Прерывание по нарастанию attachInterrupt(digitalPinToInterrupt(3), D3Int, RISING); Timer1.initialize(); Timer1.attachInterrupt(beTimeout); } byte test[8] = {0, 0, 0, 1, 1, 1, 1, 1}, test2[8] = {0, 0, 1, 1, 0, 0, 1, 1}, test3[16], c[32]; void toBinaryInt(int x, byte *array) { for (int i = 15; i >= 0; i--) { if ((1 << i) & x) array[15 - i] = 1; else array[15 - i] = 0; } } void toBinary(int x, byte *array) { for (int i = 3; i >= 0; i--) { if ((1 << i) & x) array[3 - i] = 1; else array[3 - i] = 0; } } void toBinaryDivPart(double divPart, byte *array) { double _intpart; double _divpart_tmp = divPart; for (int i = 4; i <= 7; i++) { divPart = _divpart_tmp * 2; _divpart_tmp = modf(divPart, &_intpart); array[i] = _intpart; } } int pwd_count = 0; int val = 0; int mod_digital = 0; void loop() { Serial.println(onSecondImpulsSend); Serial.print("current mode: "); Serial.println(mode); //mode 5 режим работы для получения характеристик двигателя if (mode == 5) { val = 5; toBinary(val, test); toBinaryDivPart(0.475, test); toBinary(7, test2); toBinaryDivPart(0.475, test2); memcpy(c, test, sizeof(byte) * 8); memcpy(&c[8], test2, sizeof(byte) * 8); mode = 0; } else //mode 7 - режим работы для управления двигателем if (mode == 7) { if (digitalRead(8) == 1) { memset(c, 0, sizeof(c) / sizeof(c[0])); mode = 0; //for stopping } //частота для ШИМ if (pwd_freq>=10 && pwd_freq<60) TCCR2B = TCCR2B & B11111000 | B00000111 | 0x06; else if (pwd_freq>=60 && pwd_freq<100) TCCR2B=TCCR2B & 0b11111000 | 0x05; //61 Гц else if (pwd_freq>=100 && pwd_freq<240) TCCR2B & B11111000 | B00000110; //125 else if (pwd_freq>=240 && pwd_freq<350) TCCR2B & B11111000 | B00000101 | 0x04; //244 Гц else if (pwd_freq>=350) TCCR2B & B11111000 | B00000101; //245 if (val < 15) val++; else val = 0; pwd_count = 5 * val; toBinary(val, test); toBinaryDivPart(0.475, test); toBinary(10 - val, test2); toBinaryDivPart(0.475, test2); toBinaryInt(onSecondImpulsSend, test3); memcpy(c, test, sizeof(byte) * 8); memcpy(&c[8], test2, sizeof(byte) * 8); memcpy(&c[16], test3, sizeof(byte) * 16); analogWrite(writePWMpin,127); } else { mode=0; analogWrite(writePWMpin,0); } delay(1000); } void receiveData(int b) { if (mode == 0) mode = Wire.read(); if (mode == 7) { while (Wire.available()) { pwd_freq = Wire.read()*10; } Serial.print("Received value: "); Serial.println(pwd_freq); } } void sendData() { Wire.write(c, 32); } // Приращение счетчика по прерыванию void D3Int() { onSecondImpulsCounter++; } //каждую секунду сбрасываем счетчик void beTimeout(){ onSecondImpulsSend=onSecondImpulsCounter; onSecondImpulsCounter=0; }
Я возможно невнятно выразился, или неправильно описал проблему? Попробую коротко - проблема в том что перестает работать i2c.
Подозреваю, что конфликт с библой TimerOne, беглое гугление выдало что-то похожее (не вчитывался, но вдруг поможет):
http://forum.arduino.cc/index.php?topic=198283.0
Извиняюсь что делаю такой "некропост". Проблема была в заземлении - провод еле-еле держался из-за чего и происходил сбой.
Вот так всегда бывает, пиняешь на софт, а виновен хард. Я обычно лампочкой ( светодиодом) прозваниваю, благо всегда под рукой(не забывать резистор)