При подключении питания НЕ перезагружается Arduino nano

sm4511022
Offline
Зарегистрирован: 11.05.2016

Доброго времени суток.

Моя схема состоит из arduino nano (atmega 328p), дисплея Nokia 5110, сервопривода SG90, двух светодиодов и кнопки. По задумке, в начале сервопривод поворачивается в положение 90 градусов (закрывает коробку), включается красный светодиод, на экране появляется игра, с помощью кнопки нужно пройти эту игру, после прохождения загорается зеленый светодиод и сервопривод отьезжает на 180 градусов и открывает коробку.

От компьтера все работает как нужно, а вот при подключении ардуины к переносной зарядке или при питании от кроны (напрямую без стабилизатора к порту VIN) уже проблема. При первом подключении к переносной зарядке (или кроне), сразу же чуть дребежжит серва, появляется подсветка на дисплее, но дальше ничего не происходит (серва не переходит в положение 90 градусов, на дисплее ничего не появляется, светодиод не загорается). При этом если я нажму на кнопку переагрузки на ардуине, все нормально заработает. Или если быстро выну и обратно вставлю провод переносной зарядки, произойдет перезагрузка ардуины и все зарабтает как надо.

Чувствую что проблема в питании, наверное при подключении питания, питание сразу иде на дисплей+серву+ардуину и ардуина не успевает прогрузится. Посоветуйте что делать, пока что я вижу решение - приделать отдельную кнопку для перезагрузки ардуины, чтобы при подключении внешнего питания перезагружать ее

[spoiler]

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <Servo.h>

Adafruit_PCD8544 display = Adafruit_PCD8544(12, 11, 10, 9, 8);


#include "Sprite.h"
#include "Chym.h"
#include "Bar.h"

Chym player;
Bar bar; 
Bar bar2;
int gameScore = 0;
int KNOCK_PIN = 3;
int SERVO_PIN = 7;
int LED_PIN_RED = 5;
int LED_PIN_GREEN = 6;
boolean clicked = false;

unsigned long gameTimerGo = millis();
int gameTimer = 0;
Servo servo;
void loop(){
}

void resetGame() {
  player.respawn();
  bar.setPos(0, 20);
  bar2.setPos(50, 30);
  gameScore = 0;
  gameTimerGo = millis();
  gameTimer = 0;
}

void setup() {
  delay(300);
  servo.attach(SERVO_PIN);
  delay(100);
  servo.write(90);
  delay(500);
  servo.detach();
  delay(1000);
  display.begin();
  display.setContrast(60);
  display.clearDisplay();
  display.display();
  pinMode(KNOCK_PIN, INPUT_PULLUP);
  pinMode(LED_PIN_RED, OUTPUT);
  pinMode(LED_PIN_GREEN, OUTPUT);
  digitalWrite(LED_PIN_RED, HIGH);
  digitalWrite(LED_PIN_GREEN, LOW);

  resetGame();

  while(1) {
    getInput();
    player.update();
    bar.update(); 
    bar2.update();
    drawLCD();
  }
}

void getInput() {
  int knock = digitalRead(KNOCK_PIN);
  if (knock == 0) { // push down
    clicked = true;
  } 
  else {
    clicked = false;
  }
}

void drawLCD() {
  display.clearDisplay();
  display.setCursor(0,0);
  gameTimer = (millis() - gameTimerGo) / 1000;
  display.print(gameTimer);
  if (!player.isDead()) {
    int ht1 = bar.hitTest(player.getX(), player.getY());
    int ht2 = bar2.hitTest(player.getX(), player.getY());
    int die = ht1 + ht2;
    if (die == 1) {
      // game over
      player.die();
    }
    if (clicked) {
      player.flyUp();
    } 
    else {
      player.cancelJump();
    }
    player.render();	
    bar.render(); 
    bar2.render(); 
  } 
  else {
    delay(400);
    display.clearDisplay();
    display.setCursor(0, 0);
    display.setTextSize(1);
    display.println(" YOU SURVIVED");
    display.print("    ");
    display.print(gameTimer);
    display.println(" sec.");
        if(gameTimer >= 3) {
            servo.attach(SERVO_PIN);
            delay(100);
          servo.write(180);
          digitalWrite(LED_PIN_RED, LOW);
          digitalWrite(LED_PIN_GREEN, HIGH);
    }
    display.display();
    delay(1000);
    display.println();
    display.println("press to start");
    display.display();
    clicked = false;
    while(!clicked) {
      getInput(); 
      delay(50);
    }
    resetGame();
  }
  display.display();
}

[/spoiler]

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

bizzon
Offline
Зарегистрирован: 29.03.2016

Ну так либо мощности не хватает у источника питания ( крона ), либо пульсации напряжения большие ( от зарядки). Либо и то и другое в совокупе. Померяйте 5 вольт хотя бы тестером- что там у вас при включении? А дальше в топ про питание. Для начала поставить поближе к серве конденсатор по питанию микрофарад на 1000.

sm4511022
Offline
Зарегистрирован: 11.05.2016

bizzon пишет:

Ну так либо мощности не хватает у источника питания ( крона ), либо пульсации напряжения большие ( от зарядки). Либо и то и другое в совокупе. Померяйте 5 вольт хотя бы тестером- что там у вас при включении? А дальше в топ про питание.

Пока нет врозможностри померить напряжение, могу сказать что переносная зарядка на 6 LI-ION аккумуляторах, подключенных паралелльно (вытащенных из батареи ноутбука). Питания, по всей видимости, не хватает чтобы побороть начальный импульс при включении, потому что когда переносная зарядка (или крона) уже подключены, и я жму на кнопку ресет на ардуине, после ресета все включается.

Вижу способы решения проблемы - либо сделать так чтобы при подключении питания происходила перезагрузка микроконтроллера, либо чтобы сначала питание получал дисплей, потом, через задержку, микроконтроллер (без сервы проблема такая-же), либо как-то побороть эти пульсации вначале

sm4511022
Offline
Зарегистрирован: 11.05.2016

Решил проблему, поставив конденсатор на 4,7 мкФ между выводами RST и GND, теперь перезагрузка при подключении питания происходит всегда

bizzon
Offline
Зарегистрирован: 29.03.2016

Не ресетом единым.. Если не наладить нормальное питание- будет периодически всё виснуть при срабатывании сервы.

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

Ну почему? RC-цепь на reset - стандартное решение.