Нашел у себя ЖК дисплей 1602 с переходником на интерфейс I2C (что за зверь такой - см. здесь).
Измерил энергопотребление: 5,4 мА (кратковременно до 6,5 мА) потребляет сам дисплей с переходником и 19 мА - подсветка при напряжении питания 5 В. Выпаял светодиод питания на I2C переходнике - ток снизился до 2,3 мА (3,4 в пике). Подсветку повесил на PWM-пин (D5), благодаря чему ее ток можно значительно снизить, при этом информация на дисплее останется вполне читабельной. Питание самого дисплея с переходником коммутируется пином D4.
Обнаружилась одна неприятная особенность дисплея: при уменьшении напряжения питания "плывет" контрастность, приходится подкручивать подстроечный резистор на I2C переходнике. Пока придумал только такой вариант - внешний подстроечный резистор для управления контрастностью дисплея. Пожалуй оставлю этот дисплей в проекте.
Текущая схема:
Для дисплея использовал библиотеку отсюда. У моей версии I2С переходника адрес 0x3F.
Вернулся к setup() и loop(), так как не удалось "завести" дисплей без них.
Собственно код (просыпаемся по нажатию кнопки, показываем в течение 5 секунд приветствие на дисплее и засыпаем):
//код++
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// для ЖК дисплея 1602 с I2C
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// кнопка
#define BUTTON_PIN 2
// Подключение дисплея
// LCD 1602 I2C <---> Arduino
// GND <------------> GND
// VCC <------------> D4
// SDA <--------> A4
// SCL <--------> A5
// A <--------------> D5
#define LCD_POWER_PIN 4
#define LCD_BACKLIGHT_PIN 5
#define LCD_BACKLIGHT_VALUE 50
// устанавливаем адрес дисплея
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
void m_sleep();
void m_wake_up();
void lcd_on();
void lcd_off();
void lcd_show();
void setup() {
// все пины на выход и в низкий уровень
for (byte i = 0; i <= A3; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
// установливаем на пине с кнопкой подтяжку к VCC
pinMode(BUTTON_PIN, INPUT);
digitalWrite(BUTTON_PIN, HIGH);
// устанавливаем обработчик прерывания INT0
attachInterrupt(0, m_wake_up, FALLING);
}
void loop() {
// засыпаем
m_sleep();
lcd_on();
lcd_show();
_delay_ms(5000);
lcd_off();
}
void m_sleep() {
// все пины на выход и в низкий уровень
for (byte i = 0; i <= A7; i++) {
// на второй ноге висит прерывание, поэтому ее не трогаем
if (i == 2) continue;
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
// отключаем АЦП
ADCSRA = 0;
// отключаем всю периферию
power_all_disable ();
// устанавливаем режим сна - самый глубокий, здоровый сон :)
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
// разрешаем спящий режим
sleep_enable();
// разрешаем прерывания
sei();
// собственно засыпаем
sleep_cpu();
}
void m_wake_up () {
// запрещаем прерывания
cli();
// запрещаем режим сна
sleep_disable();
// включаем периферию
power_all_enable();
}
///////////////////////////////////////////////////////////////////////////////
// LCD 1602 I2C
void lcd_on() {
digitalWrite(LCD_POWER_PIN, HIGH);
analogWrite(LCD_BACKLIGHT_PIN, LCD_BACKLIGHT_VALUE);
}
void lcd_off() {
digitalWrite(LCD_POWER_PIN, LOW);
digitalWrite(LCD_BACKLIGHT_PIN, LOW);
}
void lcd_show() {
// инициализируем дисплей
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Hello, world!");
}
//код--
Или здесь.
Измерил энергопотребление: 5,4 мА (кратковременно до 6,5 мА) потребляет сам дисплей с переходником и 19 мА - подсветка при напряжении питания 5 В. Выпаял светодиод питания на I2C переходнике - ток снизился до 2,3 мА (3,4 в пике). Подсветку повесил на PWM-пин (D5), благодаря чему ее ток можно значительно снизить, при этом информация на дисплее останется вполне читабельной. Питание самого дисплея с переходником коммутируется пином D4.
Обнаружилась одна неприятная особенность дисплея: при уменьшении напряжения питания "плывет" контрастность, приходится подкручивать подстроечный резистор на I2C переходнике. Пока придумал только такой вариант - внешний подстроечный резистор для управления контрастностью дисплея. Пожалуй оставлю этот дисплей в проекте.
Текущая схема:
Для дисплея использовал библиотеку отсюда. У моей версии I2С переходника адрес 0x3F.
Вернулся к setup() и loop(), так как не удалось "завести" дисплей без них.
Собственно код (просыпаемся по нажатию кнопки, показываем в течение 5 секунд приветствие на дисплее и засыпаем):
//код++
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// для ЖК дисплея 1602 с I2C
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// кнопка
#define BUTTON_PIN 2
// Подключение дисплея
// LCD 1602 I2C <---> Arduino
// GND <------------> GND
// VCC <------------> D4
// SDA <--------> A4
// SCL <--------> A5
// A <--------------> D5
#define LCD_POWER_PIN 4
#define LCD_BACKLIGHT_PIN 5
#define LCD_BACKLIGHT_VALUE 50
// устанавливаем адрес дисплея
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
void m_sleep();
void m_wake_up();
void lcd_on();
void lcd_off();
void lcd_show();
void setup() {
// все пины на выход и в низкий уровень
for (byte i = 0; i <= A3; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
// установливаем на пине с кнопкой подтяжку к VCC
pinMode(BUTTON_PIN, INPUT);
digitalWrite(BUTTON_PIN, HIGH);
// устанавливаем обработчик прерывания INT0
attachInterrupt(0, m_wake_up, FALLING);
}
void loop() {
// засыпаем
m_sleep();
lcd_on();
lcd_show();
_delay_ms(5000);
lcd_off();
}
void m_sleep() {
// все пины на выход и в низкий уровень
for (byte i = 0; i <= A7; i++) {
// на второй ноге висит прерывание, поэтому ее не трогаем
if (i == 2) continue;
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
// отключаем АЦП
ADCSRA = 0;
// отключаем всю периферию
power_all_disable ();
// устанавливаем режим сна - самый глубокий, здоровый сон :)
set_sleep_mode (SLEEP_MODE_PWR_DOWN);
// разрешаем спящий режим
sleep_enable();
// разрешаем прерывания
sei();
// собственно засыпаем
sleep_cpu();
}
void m_wake_up () {
// запрещаем прерывания
cli();
// запрещаем режим сна
sleep_disable();
// включаем периферию
power_all_enable();
}
///////////////////////////////////////////////////////////////////////////////
// LCD 1602 I2C
void lcd_on() {
digitalWrite(LCD_POWER_PIN, HIGH);
analogWrite(LCD_BACKLIGHT_PIN, LCD_BACKLIGHT_VALUE);
}
void lcd_off() {
digitalWrite(LCD_POWER_PIN, LOW);
digitalWrite(LCD_BACKLIGHT_PIN, LOW);
}
void lcd_show() {
// инициализируем дисплей
lcd.begin(16,2);
lcd.setCursor(0,0);
lcd.print("Hello, world!");
}
//код--
Или здесь.
Комментариев нет:
Отправить комментарий