Архив метки: arduino mega

Управление питанием при помощи Arduino. Часть третья.

В продолжение части 1 и части 2. выкладываю электрическую схему по подключению. Любезно предоставлено Фёдоровым Александром, далее текст и схемы — его.

Для осуществления развязки по питанию блока релле и основной платы Arduino, а также возможности прошивки через USB без включения внешнего питания рекомендуется подача рабочего питания +5V во внутреннюю линию 5V после преобразователя IC1 через внешний диод (чтобы при питании от USB питание не попадало на блок релле и внешний блок питания). Блок релле также желательно подключать через диод для предотвращения проникновения обратных бросков с блока релле в цепь питания Arduino, при этом перемычка питания блока релле должны быть снята. Небольшое занижение питания за счет диодного перехода до 4.5V не влияет на работу блоков Arduino т.к. сам CPU этих плат запитывается через преобразователь «3.3V» (IC6) имеющий низки параметр минимального падения напряжения около 0.28V, что позволяет запитывать плату даже от 3.7 V

 

 

 

 

Запитка обмоток блока релле непосредственно с контактов питания Arduino не рекомендуется, т.к. встроенные преобразователи напряжения слаботочные (ток не более 1А) и их с натяжкой хватает для запитки самих плат Arduino! Также в цепи штатного разъема под внешнее питание присутствует слаботочный защитный диод D1, который также не расчитан на большие токи!

Программный reset для Arduino Mega

Увы.. Работа Arduino Mega с сетевой картой оказалась не очень стабильной. Время от времени карта «зависает» и спасает только ресет всего устройства. Для того чтобы сделать «reset» есть два пути: 1) Подать на pin reset напряжение 2) Воспользоваться библиотекой /avr/wdt.h
Мы пойдем вторым путем..

#include <avr/wdt.h>

void loop() {
 //если давно не было подключения к интернету, думаем что контроллер завис и ресетим..
 if (millis() > fail_timer) {
 ConsPrint("RESTART ARDUINO...");
 wdt_enable(WDTO_15MS);
 delay(1500);
};
 ...

Значения могут быть следующие:

WDTO_15MS
WDTO_30MS
WDTO_60MS
WDTO_120MS
WDTO_250MS
WDTO_500MS
WDTO_1S
WDTO_2S
WDTO_4S
WDTO_8S

,т.е. «назначаем рестарт через столько то времени». Но! Есть еще и возможность успеть сбросить таймер перезапуска : wdt_reset(); или вовсе отменить: wdt_disable();

Используя этот функционал мы например можем сделать следующую логику приложения:

запускаем таймер «ресет через 5 секунд»
запускаем «опасный для зависания код»
если код выполнился — сбрасываем таймер, перезагрузки не будет
если код не выполнился — произойдет автоматическая перезагрузка arduino

Русификация utft для arduino

Итак, пришел наконец дисплейчик на микросхеме HX8357B.  Подключил — работает. Демки показывает которые идут к библиотеке utft (взять можно здесь). Да вот беда — русский то шрифт (кириллицу) ожидаемо не поддерживает. Будем исправлять. Первым делом роем интернет. Находим два решения: тут и тут. Первое не интересно тем, что для вывода на экран в кириллице требуется писать код вида:

 myGLCD.print("\x97""o""\x99""a", x, y);

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

Итог: на основе этих двух решений разработано собственное:

  1. Устанавливаем библиотеку utft
  2. Создаем пустой проект, сохраняем его
  3. В папку проекта закидываем вот этот шрифт: RussianFonts
  4. Далее в проект вставляем следующий код:
#include <UTFT.h>
#include <memorysaver.h>

UTFT tft(CTE32HR,38,39,40,41);
extern uint8_t SmallRusFont[];
extern uint8_t BigRusFont[];

const uint8_t utf8_rus_charmap[] PROGMEM = {'A',128,'B',129,130,'E',131,132,133,134,135,'K',136,'M','H','O',137,'P','C','T',138,139,'X',140,141,
142,143,144,145,146,147,148,149,'a',150,151,152,153,'e',154,155,156,157,158,159,160,161,162,'o',163,'p','c',164,'y',165,'x',166,167,168,169,170,
171,172,173,174,175};

void printRus(UTFT rus,char *st, int x, int y, int deg){
 int stl, i;
 stl = strlen(st);
 if (rus.orient==PORTRAIT){
	if (x==RIGHT) x=(rus.disp_x_size+1)-(stl*rus.cfont.x_size);
	if (x==CENTER) x=((rus.disp_x_size+1)-(stl*rus.cfont.x_size))/2;
 } else {
  if (x==RIGHT) x=(rus.disp_y_size+1)-(stl*rus.cfont.x_size);
  if (x==CENTER) x=((rus.disp_y_size+1)-(stl*rus.cfont.x_size))/2;
 }
 uint8_t utf_high_byte = 0;
 uint8_t ch, ch_pos = 0;
 for (i = 0; i < stl; i++) {
  ch = st[i];
   if ( ch >= 128) {
     if ( utf_high_byte == 0 && (ch ==0xD0 || ch == 0xD1)) {
         utf_high_byte = ch;
	  continue;
     } else {
     if ( utf_high_byte == 0xD0) {
	if (ch == 0x81) { //Ё
	  ch = 6;
	} else {
	if(ch <= 0x95) {
	   ch -= 0x90;
	} else if( ch < 0xB6){
	ch -= (0x90 - 1);
	} else {
	ch -= (0x90 - 2);
	}}
	ch = pgm_read_byte(utf8_rus_charmap + ch);
    } else if (utf_high_byte == 0xD1) {
           if (ch == 0x91) {//ё
	       ch = 39;
	   } else {
	    ch -= 0x80;
	    ch += 50;
	   }
           ch = pgm_read_byte(utf8_rus_charmap + ch);
	}
	utf_high_byte = 0;
   }
   } else {
     utf_high_byte = 0;
     }
     if (deg==0) {rus.printChar(ch, x + (ch_pos * (rus.cfont.x_size)), y);} else {
		  rus.rotateChar(ch, x, y, ch_pos, deg);
		}
      ++ch_pos;
 }
};
void setup(){  
  tft.InitLCD(LANDSCAPE);
  tft.clrScr();
  tft.setColor(VGA_BLACK);
  tft.fillRect(0,0, tft.getDisplayXSize()-1, tft.getDisplayYSize()-1);
  tft.setFont(BigRusFont);
  tft.setColor(VGA_WHITE);
  tft.setBackColor(VGA_TRANSPARENT);
  printRus(tft,"АБВГДЕЁЖЗИЙКЛМН", 0, 0,0);

  printRus(tft,"ОПРСТУФХШЩЬЫЪЭ", 0, 20,0); 
  printRus(tft,"ЮЯабвгдеёжзийкл", 0, 40,0);
  printRus(tft,"мнопрстуфхцчшщь", 0, 60,0);
  printRus(tft,"ыъэюя", 0, 80,0);
  tft.setFont(SmallRusFont);
  printRus(tft,"АБВГДЕЁЖЗИЙКЛМН", 0, 100,0);

  printRus(tft,"ОПРСТУФХШЩЬЫЪЭ", 0, 120,0); 
  printRus(tft,"ЮЯабвгдеёжзийкл", 0, 140,0);
  printRus(tft,"мнопрстуфхцчшщь", 0, 160,0);
  printRus(tft,"ыъэюя", 0, 180,0);
}

void loop()
{
}


Заливаем скетч в Arduino..и вуаля, получаем картинку вида:

04.08.15 - 1