Склепал 2 скетча один передает 2 координаты а второй принимает эти координаты... отдельно все работает.... А дальше ту часть которая принимает попытался скрестить с основной частью проекта и вот после этого засада монитор молчит... помогите плиз разобраться... рабочий скетчь приемника.. Код (C++): #include <RCSwitch.h> RCSwitch mySwitch = RCSwitch(); #define key1 300000 #define key2 303000 int q; // с передатчика int z; // с передатчика void setup() { Serial.begin(9600); mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin #2 // иницилизация.Используется вывод м/к с прерыванием под номером 0. } void loop() { if (mySwitch.available()) { while (!Serial); unsigned long receivedCode= mySwitch.getReceivedValue(); if (receivedCode == 0) { // обработка:не верный формат данных } else { if (key1<=receivedCode && key1+999>receivedCode) q=(int)(receivedCode-key1); else if (key2<=receivedCode && key2+999>receivedCode) z=(int)(receivedCode-key2); } mySwitch.resetAvailable(); // сброс данных. } // end available // тут могут выводится данные tempout и tempin на лсд экран или отправлятся через езернет. Serial.print("peremennaya---"); Serial.print(q); delay(500); Serial.print("vtoraya---"); Serial.print(z); } А это код после того как скрестил с основным вышеразмещенный приемник Код (C++): #include <Wire.h> #include <HMC5883L.h> #include <MPU6050.h> #include <I2Cdev.h> #include <Servo.h> #include <EEPROM.h> #include <RCSwitch.h> Servo myservo; RCSwitch mySwitch = RCSwitch(); HMC5883L compass; MPU6050 mpu; #define key1 300000 #define key2 303000 int q; // с передатчика int z; // с передатчика int addr = 0;//адрес старта памяти 0-512 int addr1 = 1;//адрес старта памяти 0-512 int error = 0; float heading1; // компасс без компенсации с дробью float heading2; //компасс с компенсацией с дробью int headingx; //Компасс целое число компенсацией рабочая лошадь+++++++++ int headingy; //Компасс целое число без компенсации const int max = 360; // максимум const int max2 = 170; // максимум для сервы с датчиками const int min = 0; // минимум const int min2 = 10; // минимум int dir = EEPROM.read(addr1); // переменная, хранящая направлени (не забыть ниже прописать!!!!!!) int IN3 = 5; int IN4 = 4; int ENB = 3; int tol = 6; // допустимая точность удерживания направления int pos2 = EEPROM.read(addr); //серва для вращения датчиков старт 90 градусов long previousMillis = 0; // храним время последнего считывания long interval = 120000; //интервал 2 для записи pos2 и dir в память //---------------------------------------------------------------------------------------------------------- void setup() { Serial.begin(9600); Wire.begin(); myservo.attach(9); mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin #2 // иницилизация.Используется вывод м/к с прерыванием под номером 0. pinMode(13, OUTPUT); pinMode (ENB, OUTPUT); pinMode (IN3, OUTPUT); pinMode (IN4, OUTPUT); //---------------------------------------------------------------- // Initialize MPU6050 while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { delay(500); } // Enable bypass mode mpu.setI2CMasterModeEnabled(false); mpu.setI2CBypassEnabled(true) ; mpu.setSleepEnabled(false); // Initialize Initialize HMC5883L while (!compass.begin()) { delay(500); } // Set measurement range compass.setRange(HMC5883L_RANGE_1_3GA); // Set measurement mode compass.setMeasurementMode(HMC5883L_CONTINOUS); // Set data rate compass.setDataRate(HMC5883L_DATARATE_30HZ); // Set number of samples averaged compass.setSamples(HMC5883L_SAMPLES_8); // Set calibration offset. See HMC5883L_calibration.ino compass.setOffset(0, 0); } // No tilt compensation float noTiltCompensate(Vector mag) { float heading = atan2(mag.YAxis, mag.XAxis); return heading; } // Tilt compensation float tiltCompensate(Vector mag, Vector normAccel) { // Pitch & Roll float roll; float pitch; roll = asin(normAccel.YAxis); pitch = asin(-normAccel.XAxis); if (roll > 0.78 || roll < -0.78 || pitch > 0.78 || pitch < -0.78) { return -1000; } // Some of these are used twice, so rather than computing them twice in the algorithem we precompute them before hand. float cosRoll = cos(roll); float sinRoll = sin(roll); float cosPitch = cos(pitch); float sinPitch = sin(pitch); // Tilt compensation float Xh = mag.XAxis * cosPitch + mag.ZAxis * sinPitch; float Yh = mag.XAxis * sinRoll * sinPitch + mag.YAxis * cosRoll - mag.ZAxis * sinRoll * cosPitch; float heading = atan2(Yh, Xh); return heading; } // Correct angle float correctAngle(float heading) { if (heading < 0) { heading += 2 * PI; } if (heading > 2 * PI) { heading -= 2 * PI; } return heading; } //------------------------------------------------------------------------------------------- void loop(){ //----------------------------------------------------------------------------------------- unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) {////проверяем не прошел ли нужный интервал, если прошел то previousMillis = currentMillis; //// сохраняем время последнего переключения EEPROM.write(addr, pos2); EEPROM.write(addr1, dir); delay(10); } //------------------------------------------------------------------------------------------- if (mySwitch.available()) { while (!Serial);// без этого на леонардо не показывает монитор unsigned long receivedCode= mySwitch.getReceivedValue(); if (receivedCode == 0) { // обработка:не верный формат данных } else { if (key1<=receivedCode && key1+999>receivedCode) q=(int)(receivedCode-key1); else if (key2<=receivedCode && key2+999>receivedCode) z=(int)(receivedCode-key2); } mySwitch.resetAvailable(); // сброс данных. } // end available dir = map(q, 0, 120, 0, 360); // Конвертируем значения для вывода в монитор и на экран pos2 = map(z, 0, 120, 0, 180); // Конвертируем значения для вывода в монитор и на экран delay(50); //---------------------------------------------------------------------------------------------------- // Read vectors Vector mag = compass.readNormalize(); Vector acc = mpu.readScaledAccel(); // Calculate headings heading1 = noTiltCompensate(mag); heading2 = tiltCompensate(mag, acc); if (heading2 == -1000) { heading2 = heading1; } // Set declination angle on your location and fix heading // You can find your declination on: http://magnetic-declination.com/ // (+) Positive or (-) for negative // For Bytom / Poland declination angle is 4'26E (positive) // Formula: (deg + (min / 60.0)) / (180 / M_PI); float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI); heading1 += declinationAngle; heading2 += declinationAngle; // Correct for heading < 0deg and heading > 360deg heading1 = correctAngle(heading1); heading2 = correctAngle(heading2); // Convert to degrees heading1 = heading1 * 180/M_PI; heading2 = heading2 * 180/M_PI; int headingx = (int)heading2; int headingy = (int)heading1; ///////////////////////////////////////////////////////////////////////// int dif = headingx - dir; // вычисляем разницу между реальным направлением и заданным int absdif = abs(dif); if (absdif <= tol) Stop(); // если разница меньше допустимой погрешности, то останавливаемся else if (((absdif > 180) && (dif != absdif)) || ((absdif < 180) && (dif == absdif))) TurnLeft(); // иначе определяем кратчайшее направление поворота else TurnRight(); if(dir > max) // проверяем выход за пределы верхней границы { dir = dir - max; } if(dir < min) // проверяем выход за пределы нижней границы { dir = max - dir; } if(pos2 > max2) // проверяем выход за пределы верхней границы { pos2 = max2; } if(pos2 < min2) // проверяем выход за пределы нижней границы { pos2 = min2; } myservo.write(pos2); delay(25); // waits 15ms for the servo to reach the position //------------------------------------------------------------------------- Serial.print(dir); Serial.print("-dir : "); Serial.print(headingx); Serial.print("- headingx : "); Serial.print(pos2); Serial.print("-pos2 : "); Serial.print(q); Serial.print("q : "); Serial.print(z); Serial.print("z : "); //------------------------------------------------------------------------- } // конец основной программы, начинаем все сначала void Stop(){ // подпрограмма Остановка digitalWrite (IN3, LOW); digitalWrite (IN4, LOW); analogWrite(ENB,0); delay(200); } void TurnRight(){ // подпрограмма Поворот направо digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); analogWrite(ENB,255); delay(100); } void TurnLeft(){ // подпрограмма Поворот налево digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); analogWrite(ENB,255); delay(100); }
Плиззз очень прошу.... Перепроверил все, пробовал в другую плату загрузить... никак не выходит-а это финальная часть моего проекта.... без этого никак....
Код (C++): unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) {////проверяем не прошел ли нужный интервал, если прошел то previousMillis = currentMillis; //// сохраняем время последнего переключения EEPROM.write(addr, pos2); EEPROM.write(addr1, dir); delay(10); } Так делать нельзя, EEPROM имеет ограниченное количество циклов перезаписи и быстро сдохнет при таком использовании.
Закомментируйте все, что добавили. Убедитесь, что работает. Начинайте открывать закомментированные строки маленькими кусками и найдете тот участок, который все портит.
А как лучше сделать? Я просто посчитал что раз в 2 минуты перезапись одной ячейки при неприрывной работе хванит месяцев на много))) а потом переключить на сдедующую из 512
попробую.... но там почти весь код надо коментировать-и после каждой строчки вливать в плпту...... так то он компилируется-просто когда пытаюсь открыть монитор-там пусто----думаю может я что то с монитором напортачил он ошибок не дает вот в чем беда
Например, можно использовать флэшку. Еще вариант - FRAM. И подумайте еще, действительно ли нужно сохраняться так часто? Отсутствие ошибок при компиляции показывает только то, что код написан правильно с точки зрения синтаксиса языка. Ошибок в логике никакой компилятор не покажет - он же не знает, что вы хотите сделать. Можно открывать сразу большой кусок. Если перестало работать - комментируете половину этого куска и снова проверяете. Потом половину половины и так далее - принцип дихотомии.
Спасибо буду пытаться... Флешку мне некуда там))) FRAM-этого я еще не проходил)))посмотрю.... Ну мне казалось если не часто переписывать то ресурса в 100000 циклов должно хванить на долго-а там 512 таких ячеек.... очень долго выходит
это я наверное не осилю пока...... логика понятна потом поищу примеры как сделать..... пока надо разобраться почему не работает..... вроде все как пологается..... еще раз перепроверить попытаюсь... Отключать блоками не получится так как помоему это ничего не даст компиляция то нормально проходит, а работать кусками все равно не будет.... ну вроде так.... хотя попробую и как Вы сказали-все равно искать надо очень нужно устройство это... железо собранно а код отработать немогу никак...
Приблизительно так: Код (C++): void WriteByte(byte data) { byte addr = EEPROM.read(0);// адрес ячейки данных EEPROM.write(addr, data);// пишем if(EEPROM.read(addr) != data)// проверяем {// ошибка чтения addr++;// переход на следующую ячейку EEPROM.write(0, addr);// сохраняем адрес ячейки данных EEPROM.write(addr, data);// пишем в новую ячейку } } byte ReadByte() { return EEPROM.read(EEPROM.read(0)); } Изначально в ячейку с адресом 0 нужно записать единичку.
Вы говорили, что в изначальном варианте кода все работало, а после добавления перестало. Если так, то монитор ни при чем должен быть.
Я сливал первую часть кода который точно работал приемник...(проверял его) со второй частью которую не проверял после редактирования, так как туда нужно было переменные передавать.... до редактирования и вторая часть работала..... странно но получается затык в самом начале вышел или вообще с монитором что то.... с утра все сначала начну искать.... спасибо за помощь
С предыдущей проблеммой разобрался, теперь хочется сообразить по записи то что Вы писали.... пока не очень понятно... пытался вызвать из под millis() WriteByte(byte data) не получилось,заменил все data на dir.... и плюс хотелось бы 2 переменные держать в памяти но проверку делать из под millis() чтобы не при каждом проходе проверять а раз в пару минут..... Не можете помочь? вот мой код рабочий Код (C++): #include <Wire.h> #include <HMC5883L.h> #include <MPU6050.h> #include <I2Cdev.h> #include <EEPROM.h> #include <VirtualWire.h> #include <EasyTransferVirtualWire.h> #include <ServoTimer2.h> // the servo library #define pitchPin 4 ServoTimer2 servoPitch; HMC5883L compass; MPU6050 mpu; int q; // с передатчика int z; // с передатчика EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE{ //put your variable definitions here for the data you want to send //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO //Struct can'e be bigger then 26 bytes for VirtualWire version byte ID; int q; int z; }; //give a name to the group of data SEND_DATA_STRUCTURE mydata; int addr = 0;//адрес старта памяти 0-512 int addr1 = 1;//адрес старта памяти 0-512 int error = 0; float heading1; // компасс без компенсации с дробью float heading2; //компасс с компенсацией с дробью int headingx; //Компасс целое число компенсацией рабочая лошадь+++++++++ int headingy; //Компасс целое число без компенсации const int max = 360; // максимум const int max2 = 120; // максимум для сервы с датчиками const int min = 0; // минимум const int min2 = 60; // минимум int dir = EEPROM.read(addr1); // переменная, хранящая направлени (не забыть ниже прописать!!!!!!) int IN3 = 7; int IN4 = 6; int ENB = 5; int tol = 6; // допустимая точность удерживания направления int pos2 = EEPROM.read(addr); //серва для вращения датчиков старт 90 градусов long previousMillis = 0; // храним время последнего считывания long interval = 120000; //интервал 2 для записи pos2 и dir в память //---------------------------------------------------------------------------------------------------------- void setup() { Serial.begin(9600); Wire.begin(); ET.begin(details(mydata)); Serial.begin(9600); // Initialise the IO and ISR vw_set_ptt_inverted(true); // Required for DR3100 vw_setup(2000); // Bits per sec vw_set_rx_pin(2); vw_rx_start(); // Start the receiver PLL running servoPitch.attach(pitchPin); pinMode(13, OUTPUT); pinMode (ENB, OUTPUT); pinMode (IN3, OUTPUT); pinMode (IN4, OUTPUT); //---------------------------------------------------------------- // Initialize MPU6050 while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G)) { delay(500); } // Enable bypass mode mpu.setI2CMasterModeEnabled(false); mpu.setI2CBypassEnabled(true) ; mpu.setSleepEnabled(false); // Initialize Initialize HMC5883L while (!compass.begin()) { delay(500); } // Set measurement range compass.setRange(HMC5883L_RANGE_1_3GA); // Set measurement mode compass.setMeasurementMode(HMC5883L_CONTINOUS); // Set data rate compass.setDataRate(HMC5883L_DATARATE_30HZ); // Set number of samples averaged compass.setSamples(HMC5883L_SAMPLES_8); // Set calibration offset. See HMC5883L_calibration.ino compass.setOffset(0, 0); } // No tilt compensation float noTiltCompensate(Vector mag) { float heading = atan2(mag.YAxis, mag.XAxis); return heading; } // Tilt compensation float tiltCompensate(Vector mag, Vector normAccel) { // Pitch & Roll float roll; float pitch; roll = asin(normAccel.YAxis); pitch = asin(-normAccel.XAxis); if (roll > 0.78 || roll < -0.78 || pitch > 0.78 || pitch < -0.78) { return -1000; } // Some of these are used twice, so rather than computing them twice in the algorithem we precompute them before hand. float cosRoll = cos(roll); float sinRoll = sin(roll); float cosPitch = cos(pitch); float sinPitch = sin(pitch); // Tilt compensation float Xh = mag.XAxis * cosPitch + mag.ZAxis * sinPitch; float Yh = mag.XAxis * sinRoll * sinPitch + mag.YAxis * cosRoll - mag.ZAxis * sinRoll * cosPitch; float heading = atan2(Yh, Xh); return heading; } // Correct angle float correctAngle(float heading) { if (heading < 0) { heading += 2 * PI; } if (heading > 2 * PI) { heading -= 2 * PI; } return heading; } //------------------------------------------------------------------------------------------- void loop(){ //----------------------------------------------------------------------------------------- unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) {////проверяем не прошел ли нужный интервал, если прошел то previousMillis = currentMillis; //// сохраняем время последнего переключения EEPROM.write(addr, pos2); EEPROM.write(addr1, dir); delay(10); } //------------------------------------------------------------------------------------------- //check and see if a data packet has come in. if(ET.receiveData()){ //this is how you access the variables. [name of the group].[variable name] //since we have data, we will blink it out. if (mydata.ID == 1) { int q = mydata.q; int z = mydata.z; } } dir = map(mydata.q, 0, 254, 0, 360); // Конвертируем значения для вывода в монитор и на экран pos2 = map(mydata.z, 0, 254, 800, 1420); // Конвертируем значения для вывода в монитор и на экран servoPitch.write(pos2); delay(50); //---------------------------------------------------------------------------------------------------- // Read vectors Vector mag = compass.readNormalize(); Vector acc = mpu.readScaledAccel(); // Calculate headings heading1 = noTiltCompensate(mag); heading2 = tiltCompensate(mag, acc); if (heading2 == -1000) { heading2 = heading1; } // Set declination angle on your location and fix heading // You can find your declination on: http://magnetic-declination.com/ // (+) Positive or (-) for negative // For Bytom / Poland declination angle is 4'26E (positive) // Formula: (deg + (min / 60.0)) / (180 / M_PI); float declinationAngle = (4.0 + (26.0 / 60.0)) / (180 / M_PI); heading1 += declinationAngle; heading2 += declinationAngle; // Correct for heading < 0deg and heading > 360deg heading1 = correctAngle(heading1); heading2 = correctAngle(heading2); // Convert to degrees heading1 = heading1 * 180/M_PI; heading2 = heading2 * 180/M_PI; int headingx = (int)heading2; int headingy = (int)heading1; ///////////////////////////////////////////////////////////////////////// int dif = headingx - dir; // вычисляем разницу между реальным направлением и заданным int absdif = abs(dif); if (absdif <= tol) Stop(); // если разница меньше допустимой погрешности, то останавливаемся else if (((absdif > 180) && (dif != absdif)) || ((absdif < 180) && (dif == absdif))) TurnLeft(); // иначе определяем кратчайшее направление поворота else TurnRight(); if(dir > max) // проверяем выход за пределы верхней границы { dir = dir - max; } if(dir < min) // проверяем выход за пределы нижней границы { dir = max - dir; } if(pos2 > max2) // проверяем выход за пределы верхней границы { pos2 = max2; } if(pos2 < min2) // проверяем выход за пределы нижней границы { pos2 = min2; } delay(25); // waits 15ms for the servo to reach the position //------------------------------------------------------------------------- Serial.print(dir); Serial.print("-dir : "); Serial.print(headingx); Serial.print("- headingx : "); Serial.print(pos2); Serial.print("-pos2 : "); Serial.print(q); Serial.print("q : "); Serial.print(z); Serial.print("z : "); //------------------------------------------------------------------------- } // конец основной программы, начинаем все сначала void Stop(){ // подпрограмма Остановка digitalWrite (IN3, LOW); digitalWrite (IN4, LOW); analogWrite(ENB,0); delay(200); } void TurnRight(){ // подпрограмма Поворот направо digitalWrite (IN3, HIGH); digitalWrite (IN4, LOW); analogWrite(ENB,255); delay(100); } void TurnLeft(){ // подпрограмма Поворот налево digitalWrite (IN3, LOW); digitalWrite (IN4, HIGH); analogWrite(ENB,255); delay(100); }