Непонятное зависание и "отвисание" ардуины Нано v3.

aleut
Offline
Зарегистрирован: 20.10.2015

Накидал скетч, НАНО управляет другой ардуиной. Всё работает, но перидически зависает. Время работы от (15 до 1,5 часов). Чтобы вернуть к жизни не перегружая надо подключить юсб и нажать монитор последовательного порта, после этого все работает до следуещего зависания. Если зависла при включенном мониторе порта, то если его отключить опять всё работает. Не могу понять в чем проблема. 

#include "Wire.h"
#include <Servo.h>
#include "HMC5883L.h"
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);

Servo Privod; //управление с джойстика
Servo Rezhim;   //смена режимов
Servo Ptchk;   //путевые точки

#define pinpotR  A6    //тумблер 3 режима
#define pinpotP  A7   //тумблер запоминания точек(подкл к 2 ось джойстика)
#define potPrivod2 A1  //джойстик управления

HMC5883L compass;
 
int kurs;        // курс с компаса, действительный
int kursfix;     // зафиксированный курс
int kursD;       // отклонение курса, фиксированный минус действительный
int valD;        //  корректирующий угол поворота привода
int potPrivod = A0;  //джойстик
int val;            // угол поворота привода
int btnprvd = 11;  //тумблер переключения управления
int buttonkurs = 7; 
int val2;
 /////////////////////////////////////////////////////////////

void draw(void) {
  u8g.setFont(u8g_font_courR18r);
  u8g.setPrintPos(80, 15); 
  u8g.print(kurs);
  
  if (digitalRead(buttonkurs)  == HIGH)
      { u8g.setFont(u8g_font_courR10r);
        u8g.drawStr(35,38,"- fix -");
         u8g.setFont(u8g_font_courR18r);
         u8g.setPrintPos(45, 60);
         u8g.print(kursfix); 
            if (valD <0)
           { u8g.setFont(u8g_font_courR10r);
             u8g.setPrintPos(0, 64);
            u8g.print(valD); } 
           else 
           {   u8g.setFont(u8g_font_courR10r);
               u8g.setPrintPos(110, 64); 
               u8g.print(valD);}                               
      } 


if (map(analogRead(pinpotR), 0, 1023, 35, 150)>65 && map(analogRead(pinpotR), 0, 1023, 35, 150)<135 )
    {u8g.setFont(u8g_font_courR10r);                      //Rezhim.write(map(analogRead(pinpotR), 0, 1023, 0, 180))u8g_font_6x10r
    u8g.drawStr(0,10,"auto");}    
    else { 
      if ( map(analogRead(pinpotR), 0, 1023, 35, 150) <65 )
             {u8g.setFont(u8g_font_courR10r);
             u8g.drawStr(0,10,"stab");}
     else 
          u8g.drawStr(0,10 ,"manual");
    }
             //delay (25);
}              
 /////////////////////////////////////////////////////////////////////////////

void setup() {
  Wire.begin();
 pinMode(buttonkurs, INPUT);//тумблер фиксации курса
 pinMode(btnprvd, INPUT);  //тумблер переключения управления
   
  Privod.attach(9);   //канал привода
  Rezhim.attach(10);   //канал режима
  Ptchk.attach(6);   //канал запоминания точек
 
  compass = HMC5883L();  // создаем экземпляр HMC5883L библиотеки
  setupHMC5883L();       // инициализация HMC5883L
 //Serial.begin(9600);
 
}
void loop() {
//  val = analogRead(potPrivod);          //управление приводом  
  val = map(analogRead(potPrivod), 0, 1023, 35, 150); 
  
   float heading = getHeading(); 

  if (digitalRead(buttonkurs)  == LOW)       
           kursfix = kurs;
   
// **************управление приводом коррекция*****************************
  kursD = kursfix - kurs;               //вычисляем величину отклонения
  if (kursD > 180) kursD -= 360;    //если отклонение больше 180 град то вычитаем 360 градусов
  if (kursD < -180) kursD += 360;   //если отклонение меньше -180 град то прибавляем 360 градусов
      
  if (kursD >= -1 && kursD <= 1)
                valD = 0;   //если отклонение меньше двух градусов, не корректируем угол
   else { if  (kursD >1 && kursD <= 180)
             {   valD = map(kursD, -180 , 180 ,-150 , 150); } //угол поворота с учетом поправки 
        else  (kursD < -1 && kursD >= -180);
              {   valD = map(kursD, -180 , 180 ,-150 , 150); }   //угол поворота с учетом поправки
  }
   val2 = val + valD;
  //val2 = min(val2, 150);
 // val2 = max(val2, 35);
if (val2>=35&&val2<=150){;}//ограничение поворота
   else { if (val2 <35) 
        { val2 = 35;}
   else  
       { val2=150;}
   }
    // picture loop
  u8g.firstPage();  
  do {
    draw();
    } while( u8g.nextPage() );
 
  Rezhim.write(map(analogRead(pinpotR), 0, 1023, 35, 150));
  Ptchk.write(map(analogRead(pinpotP), 0, 1023, 35, 150));
  
 if (digitalRead(btnprvd)  == HIGH) // переключение управления приводом
      Privod.write(map(analogRead(potPrivod2), 0, 930,130,60)); //управление приводом с потенциометра 
   else 
      Privod.write(val2);       

 // Serial.println(map(analogRead(potPrivod2), 0, 930, 130, 60));
  //Serial.println(kurs);
 // Serial.println("____________"); //Serial.println(10);
 //Serial.println(kursfix);
  //delay (250);
  
}
void setupHMC5883L(){
  // инициализация HMC5883L, и проверка наличия ошибок
 /* 
  int error;  
  error = compass.SetScale(0.88); // чувствительность датчика из диапазона: 0.88, 1.3, 1.9, 2.5, 4.0, 4.7, 5.6, 8.1
  if(error != 0) Serial.println(compass.GetErrorText(error)); // если ошибка, то выводим ее
 
  error = compass.SetMeasurementMode(Measurement_Continuous); // установка режима измерений как Continuous (продолжительный)
  if(error != 0) Serial.println(compass.GetErrorText(error)); // если ошибка, то выводим ее*/
}
 
float getHeading(){
  // считываем данные с HMC5883L и рассчитываем  направление
  MagnetometerScaled scaled = compass.ReadScaledAxis(); // получаем масштабированные элементы с датчика
  float heading = atan2(scaled.YAxis, scaled.XAxis);    // высчитываем направление
   // корректируем значения с учетом знаков
  if(heading < 0) heading += 2*PI;
  if(heading > 2*PI) heading -= 2*PI;
           kurs = map(heading * RAD_TO_DEG,0,359,359,0);
   return kurs;
   }

 

Valera19701
Valera19701 аватар
Offline
Зарегистрирован: 18.10.2015

скорее всего проблема аппаратная

1) припаяйте напрямую без разъемов шину SDA и SCL

2) припаяйте керамический конденсатор емкостью 0,1 - 1 мкф параллельно питанию (VCC GND) каждого блока

а отвисает потому, что при подключении USB nano делает сброс

aleut
Offline
Зарегистрирован: 20.10.2015

отвисает не при подключении USB (он может быть уже подключенным) а именно при открытии монитора порта. С кондесаторами попробую завтра, у меня таких нет, надо прикупить.

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

При открытии монитора порта тоже сброс (reset) происходит.

aleut
Offline
Зарегистрирован: 20.10.2015

т.е. проблема не программная?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Скорее, по-другому:

в первую очередь нужно решать аппаратные проблемы, и толко после того, как все они решены - приступать к решению программных.

std
Offline
Зарегистрирован: 05.01.2012

Тот же вопрос, есть радиоуправляемая люстра с датчиком движения, которая передаёт факт движения на выключатель, чтобы подсвечивался. Никаких проблем с приёмом факта движения (т. о. от люстры к выключателю), но иногда тупка с передачей в обратном направлении, то есть пинаем люстру "включись" а она не чешется. Перезагрузишь этот выключатель и становится нормально, что заставляет думать что он не может передать. Но и не исключён вариант другой, типа люстра не может принять. Сижу чешу репу.

Проблема появлялась раз 5 за 2 месяца.

aleut
Offline
Зарегистрирован: 20.10.2015

Помогает отключение SCL, тогда не виснет. кондесаторы не влияют.

bwn
Offline
Зарегистрирован: 25.08.2014

aleut пишет:

Помогает отключение SCL, тогда не виснет. кондесаторы не влияют.

Чегой то? Еще лучше помогает совсем не подключать.

aleut
Offline
Зарегистрирован: 20.10.2015

Лучше вообще не коментировать

bwn
Offline
Зарегистрирован: 25.08.2014

aleut пишет:

Лучше вообще не коментировать

Вам же сказали, разберитесь с аппаратными проблемами, а не проводки теребите.