Работает. А почему (#define CLK 3) // Clock Подключаем к INT1, нельзя переназначать?
Не знал что (#define GT 6 // Gate Triac управление симистором) можно поменять с 4 на 6.
P,S не приходит письмо с форума, на восстановление пароля. (Kevin)
Вид для печати
Работает. А почему (#define CLK 3) // Clock Подключаем к INT1, нельзя переназначать?
Не знал что (#define GT 6 // Gate Triac управление симистором) можно поменять с 4 на 6.
P,S не приходит письмо с форума, на восстановление пароля. (Kevin)
Спасибо! значит я могу выкладывать? Хотя еще хочу немного доделать, что бы он последние настройки сохранял и управлял вкл/выкл кнопкойЦитата:
Работает.
Потому что D2 уже занят под диммер, а прерываний все 2, int0 и int1Цитата:
А почему (#define CLK 3) // Clock
Можно сделать и без прерываний, но это уже не совсем правильно, так как не будет работать в фоновом режиме
Можно на любой пин поменятьЦитата:
Не знал что (#define GT 6 // Gate Triac управление симистором) можно поменять с 4 на 6.
Рассылку почты забанили опять :(Цитата:
P,S не приходит письмо с форума, на восстановление пароля. (Kevin)
Скинул новый пароль в личку
При подключении библиотеки u8glib, лампочка при малых мощностях начинает мерцать.
Код HTML:void loop()
{
u8g.firstPage();
do {
draw();
}
while( u8g.nextPage() );
}
void draw(void) {
u8g.setFont(u8g_font_courR24n);
u8g.setPrintPos(15, 22);
u8g.print(dimmer);
}
выложи весь код посмотрю где ошибка
Хотя врятли поможет, нужно смотреть на саму либу
Скорее всего i2c при транзакции запрещает все прерывания
Бардачина в коде - экспериментировал
PHP код:
#include "U8glib.h"
#include <CyberLib.h> //Библиотека от Cyber-Place.ru
#include "rus6x12.h"
#define PAGE_HEIGHT HEIGHT
// Выводы ЭНКОДЕРА
#define CLK 3 // Clock Подключаем к INT1, нельзя переназначать
#define DT 4 // второй вывод энкодера
#define SW 5 // switch кнопка энкодера
#define ZD 2 // zero detection детектор ноля
#define GT 6 // Gate Triac управление симистором
#define Min 0 // минимальное значение диммера для устранения мерцания
#define Max 255 //максимальное значение диммера для устранения мерцания
volatile uint8_t tic, dimmer=0;
boolean DT_last; // последнее состояние энкодера
//===========================================================
U8GLIB_SSD1306_128X64 u8g(A4, /* data=*/ A3, /* cs=*/ A0, /* dc=*/ A1, /* reset=*/ A2); // наш дисплей ||
//===========================================================
int motorPin = 3;
int motorSpeed = 75; // Изначальная скорость двигателя
int fanPower = 155; // Изначальная мощность фена
int selectMode = 1; // Что изменять, скорость или мощность фена
void draw(void) {
u8g.setFont(u8g_font_courR24n);// мой тонкие цифры
u8g.setPrintPos(15, 22);
u8g.print(dimmer);
u8g.setPrintPos(15, 64);
u8g.print(motorSpeed);
if(selectMode == 1)
{
u8g.setPrintPos(78, 23);
u8g.print(".");
}
else
{
u8g.setPrintPos(78, 59);
u8g.print(".");
}
// ===================================
u8g.setPrintPos(81, 6);
u8g.setFont(rus6x12);
u8g.print("температура");
u8g.setPrintPos(84, 43);
u8g.print("обороты");
// ===================================
u8g.setFont(u8g_font_courR14r);
u8g.setPrintPos(95, 27);
u8g.print(dimmer);
u8g.setPrintPos(95, 64);
u8g.print(motorSpeed);
// ===================================
u8g.setPrintPos(-2, 70);
u8g.setFont(u8g_font_ncenR24);
u8g.print("*");
// ===================================
u8g.drawLine(77, 0, 77, 64); // Вертикальная линия
u8g.drawLine(80, 32, 128, 32); // Горизонтальная короткая линия
// u8g.drawBitmapP(0, 0, 1, 24, Termometr);
// u8g.drawBitmapP(-2, 47, 2, 14, Cooler);
}
void setup()
{
pinMode(CLK,INPUT_PULLUP); // Clock Подключаем к INT1, нельзя переназначать
pinMode(DT, INPUT_PULLUP); // второй вывод энкодера
pinMode(SW, INPUT_PULLUP); // кнопка энкодера
pinMode(ZD, INPUT); // детектор нуля
pinMode(GT, OUTPUT); // управление симистором
digitalWrite(GT, 0); // отключить симмистор
attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания int0 на низкий уровень
attachInterrupt(1, encoderTick, CHANGE); // прерывания от Энкодера
StartTimer1(halfcycle, 40); // время для одного разряда ШИМ в мкс
StopTimer1(); //остановить таймер
DT_last = digitalRead(CLK); // считываем положение CLK
// Serial.begin(115200); // для отладки
//Serial.begin( 9600 );
TCCR2B = TCCR2B & 0b11111000 | 7;
pinMode(motorPin, OUTPUT);
//======================
u8g.firstPage();
do {
u8g.drawBitmapP(0, 0, 16, 64, Logo);
} while( u8g.nextPage() );
delay (4000);
//======================
u8g.firstPage();
do {
draw();
} while( u8g.nextPage() );
//======================
}
//********************обработчики прерываний*******************************
void halfcycle() //прерывания таймера
{
tic++; //счетчик
if( dimmer < tic ) digitalWrite(GT, HIGH); //управляем выходом на симистор
}
void detect_up() // обработка внешнего прерывания. Сработает по переднему фронту
{
tic=0; //обнулить счетчик
ResumeTimer1(); //запустить таймер
attachInterrupt(0, detect_down, HIGH); //перепрограммировать прерывание на другой обработчик
}
void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту
{
StopTimer1(); //остановить таймер
digitalWrite(GT, LOW); //логический ноль на выход
tic=0; //обнулить счетчик
attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик
}
//**************************************** *********************************
void encoderTick() // Обратка прерываний от Энкодера
{
uint8_t DT_now = digitalRead(CLK); // считываем текущее положение CLK
if (DT_now != DT_last) // если предыдущее и текущее положение CLK не равны, значит был поворот
{
if (digitalRead(DT) != DT_now) // если DT не равен CLK, значит вращение по часовой стрелке
{
if( dimmer < Max )
// dimmer++; // прибавить яркость
//======================
if (selectMode == 0)
{
motorSpeed += 5; // Прибавляем скорость
if ( motorSpeed > 255 )
motorSpeed = 255;
}
else
{
dimmer++;
// fanPower -= 5; // Прибавляем мощность фена
// if ( fanPower < 0)
// fanPower = 0;
}
//======================
/* u8g.firstPage();
do {
draw();
}
while( u8g.nextPage() );*/
//======================
} else
//====================== ===================== ===================== ===================== =====================
{ // если DT равен CLK, значит вращение против часовой
if( dimmer > Min )
// dimmer--; // убавить яркость
//======================
if (selectMode == 0)
{
motorSpeed -= 5; // Убавляем скорость
if ( motorSpeed < 75 )
motorSpeed = 75;
}
else
{
dimmer--;
// fanPower += 5; // Убавляем мощность фена
// if ( fanPower > 255)
// fanPower = 255;
}
//======================
/* u8g.firstPage();
do {
draw();
}
while( u8g.nextPage() );*/
//======================
}
}
DT_last = DT_now; // сохранить положение CLK для следующей проверки
}
void loop()
{
u8g.firstPage();
do {
draw();
}
while( u8g.nextPage() );
// Serial.println(dimmer);
// delay(100);
}
А для чего вот этот цикл?
Я думаю что нужно скорость цикла уменьшить, поставить там delay(500) после drawЦитата:
do {
draw();
}
while( u8g.nextPage() );
Это обновление/вывод инфы на дисплей. Без него не работает. Вот пример из либы
PHP код:
void draw(void) {
// graphic commands to redraw the complete screen should be placed here
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_osb21);
u8g.drawStr( 0, 22, "Hello World!");
}
void setup(void) {
// flip screen, if required
// u8g.setRot180();
// set SPI backup if required
//u8g.setHardwareBackup(u8g_backup_avr_spi);
// assign default color value
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
}
void loop(void) {
// picture loop
u8g.firstPage();
do {
draw();
} while( u8g.nextPage() );
// rebuild the picture after some delay
delay(500);
}
Частота мерцания меняется. Пробовал 100 и 500. В принципе для фена это наверно не будет критично.
Для фена точно не будет критично
Ну тогда и забуду про это. Проверял мультиметром - максимум на 1 вольт скачет напруга. Кстати - опять резюк 510 дыманул, хотя и спарил 2 по 0.25w
Странно. Похоже на то что у тебя симистор не правильно подключен, а работает через симистор оптрона и через резистор. Хотя лампочка через этот резистор не должна загоратьсяЦитата:
Кстати - опять резюк 510 дыманул, хотя и спарил 2 по 0.25w
С выходных буду разбираться что к чему. Похоже так же как у меня мерцания, только не понял как они исправили
Дописал скетч, проверь если не затруднит
Теперь кнопкой можно вкл и выкл, при этом диммер сохраняет уровень яркости и состояние выключателя. Если обесточить, то диммер прочитает последние до выкл. настройки
Код:#include <CyberLib.h> //Библиотека от Cyber-Place.ru
// Выводы ЭНКОДЕРА
#define CLK 3 // Clock Подключаем к INT1, нельзя переназначать
#define DT 4 // выторой вывод энкодера
#define SW 5 // switch кнопка энкодера
#define ZD 2 // zero detection детектор ноля
#define GT 6 // Gate Triac управление симристором
#define Min 0 // минимальное значение диммера для устранения мерцания
#define Max 255 //максимальное значение диммера для устранения мерцания
volatile uint8_t tic, dimmer;
boolean DT_last, stat_sw, tmp; // последнее состояние энкодера , состояние выключателя
void setup()
{
pinMode(CLK,INPUT_PULLUP); // Clock Подключаем к INT1, нельзя переназначать
pinMode(DT, INPUT_PULLUP); // выторой вывод энкодера
pinMode(SW, INPUT_PULLUP); // кнопка энкодера
pinMode(ZD, INPUT); // детектор нуля
pinMode(GT, OUTPUT); // управление симистором
digitalWrite(GT, 0); // отключить симмистор
attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания int0 на низкий уровень
attachInterrupt(1, encoderTick, CHANGE); // прерывания от Энкодера
StartTimer1(halfcycle, 40); // время для одного разряда ШИМ в мкс
StopTimer1(); //остановить таймер
stat_sw=ReadEEPROM_Byte(1);
if(stat_sw) {dimmer=ReadEEPROM_Byte(0);}
else {dimmer=255;}
DT_last = digitalRead(CLK); // считываем положение CLK
Serial.begin(115200); // для отладки
}
void loop()
{
tmp=digitalRead(SW); //прочитать состояние кнопки
delay(50); // исключаем дребезг кнопки
if( !digitalRead(SW) && !stat_sw && !tmp)//если было нажатие кнопки и выключатель в состооянии выкл.
{
dimmer=ReadEEPROM_Byte(0);//прочитать состояние диммера
stat_sw=true;//изменить состояние выключателя
WriteEEPROM_Byte(1, stat_sw);//записать состояние выключателя
while( !digitalRead(SW)){}
StartTimer1(halfcycle, 40); //запустить таймер
}
else
if( !tmp && !digitalRead(SW) && stat_sw )//если было нажатие кнопки и состояние выключателя вкл.
{
StopTimer1(); //остановить таймер
WriteEEPROM_Byte(0, dimmer); //записать состояние диммера
dimmer=255;
stat_sw=false;//изменить состояние выключателя
WriteEEPROM_Byte(1, stat_sw); //записать состояние выключателя
while( !digitalRead(SW)){}
}
//Serial.println(dimmer);
//Serial.println(stat_sw);
delay(50);
}
//********************обработчики прерываний*******************************
void halfcycle() //прерывания таймера
{
tic++; //счетчик
if( dimmer < tic ) digitalWrite(GT, HIGH); //управляем выходом на симистор
}
void detect_up() // обработка внешнего прерывания. Сработает по переднему фронту
{
tic=0; //обнулить счетчик
ResumeTimer1(); //запустить таймер
attachInterrupt(0, detect_down, HIGH); //перепрограммировать прерывание на другой обработчик
}
void detect_down() // обработка внешнего прерывания. Сработает по заднему фронту
{
StopTimer1(); //остановить таймер
digitalWrite(GT, LOW); //логический ноль на выход
tic=0; //обнулить счетчик
attachInterrupt(0, detect_up, LOW); //перепрограммировать прерывание на другой обработчик
}
void encoderTick() // Обратка прерываний от Энкодера
{
uint8_t DT_now = digitalRead(CLK); // считываем текущее положение CLK
if (DT_now != DT_last) // если предыдущее и текущее положение CLK не равны, значит был поворот
{
if (digitalRead(DT) != DT_now) // если DT не равен CLK, значит вращение по часовой стрелке
{
if( dimmer < Max ) dimmer--; // прибавить яркость
} else { // если DT равен CLK, значит вращение против часовой
if( dimmer > Min ) dimmer++; // убавить яркость }
}
}
DT_last = DT_now; // сохранить положение CLK для следующей проверки
}
Я только после выходных смогу проверить (уехал по делам)
Скетч проверил - работает не корректно. При нажатии на кнопку лампочка загорается на полную, при повторном нажатии опять на минимум, и так циклично. Если вращать вал, и потом нажать - сохраняется в память после выключения
Так и было задумано.
Нажатие - свет включается
следующее нажатие выключается
Отрегулировал нужную яркость, нажал на кнопку, свет выключился и сохранил последние значения яркости
В том то и дело что свет не выключается. Он выключается при значении 255
Ага, я забыл про это
Ну тогда променяй dimmer=0; на dimmer=255;
Делал - выключает : ) Но не сохраняет - выкл или вкл диммер. При перезагрузке - постоянно вкл, даже если диммер был выключен.
Исправил все ошибки, проверяйте http://compcar.ru/forum/showthread.p...l=1#post112152
Проверю чуть позже. А как в WriteEEPROM_Byte(0, SetPower); записать SetPower более 255?
Цитата:
SetPower более 255?
Важен какой максимум
Если не больше 65535 то:
Код:Сохранить значение 4000 в EEPROM по адресу 0 тип Word
WriteEEPROM_Word(0, 4000);
Прочитать из EEPROM с адреса 0 значение типа Word
uint16_t tmp=ReadEEPROM_Word(0);
И нужно иметь ввиду при адресации, что в памяти занимает 2 байта
Не хочет прочитать из EEPROM
Прежде чем прочитать, сначала нужно записать или я что то не допонимаю?
: ) Так то да. Проверил Serial.println(SetPower); - читает, но почему то на экран пишет 0. u8g.print(SetPower);
P.S. Не понял что и сделал, но заработало. Видимо пора в люлю. Оказалось просто сделать, а в инете читал там число надо на части разбить - записать - потом опять собирать. Ни чего не понял, а что понял то не заработало - EEPROM.put и EEPROM.get,
А мой код работает?
Ещё не проверял. Сейчас проверю - дополню
Да работает - сохраняет, только регулировку надо переделать - поменять местами + с минусом. Я у себя переделал. А то по часовой стрелке убавляется яркость, и наоборот.
что именно переделал? Я вроде на сериал мониторе смотрел, все работало как положено
Ты в сериал мониторе что видел? Прибавлялись значения при вращении энкодера по часовой и уменьшались против часовой? А диммер "тухнет" при 255
PHP код:
void encoderTick() // Обратка прерываний от Энкодера
{
uint8_t DT_now = digitalRead(CLK); // считываем текущее положение CLK
if (DT_now != DT_last) // если предыдущее и текущее положение CLK не равны, значит был поворот
{
if (digitalRead(DT) != DT_now) // если DT не равен CLK, значит вращение по часовой стрелке
{
if( dimmer < Max ) dimmer--; // прибавить яркость тут минус
} else { // если DT равен CLK, значит вращение против часовой
if( dimmer > Min ) dimmer++; // убавить яркость а тут плюс
}
}
DT_last = DT_now; // сохранить положение CLK для следующей проверки
}
Кручу по часовой и значения уменьшаются , кручу против увеличиваются
Скорее всего у тебя диммер по другому подклюбчен, местами clk, dt перевернуты
Я уже думал об этом - поменять местами. Хотя у меня CLK 3 а DT 4
вот такой модуль
Вложение 19346
Извиняюсь, это у меня перепутаны местами
Я забыл что в другом проекте их поменял http://cyber-place.ru/showthread.php?t=2703
А где можно почитать про метод работы с EEPROM, что используется в данном примере.
Библиотека cyberlib для ардуины http://cyber-place.ru/showthread.php?t=550
Цитата:
*********EEPROM
Ограничение! адресует максимум 256 адресов для типа Byte
Для Word максимум 128
Для Long максимум 64
Сохранить значение 4000000 в EEPROM по адресу 0 тип Long
WriteEEPROM_Long(0, 4000000);
Прочитать из EEPROM с адреса 0 значение типа Long
uint32_t tmp=ReadEEPROM_Long(0);
Сохранить значение 4000 в EEPROM по адресу 0 тип Word
WriteEEPROM_Word(0, 4000);
Прочитать из EEPROM с адреса 0 значение типа Word
uint16_t tmp=ReadEEPROM_Word(0);
Сохранить значение 400 в EEPROM по адресу 0 тип Byte
WriteEEPROM_Byte(0, 200);
Прочитать из EEPROM с адреса 0 значение типа Byte
uint8_t tmp=ReadEEPROM_Byte(0);
Спасибо, почитаю на досуге. А про stm32 не будет ли полезных статеек. А то контроллер валяется без дела.
К сожалению я пока не имел с ними дела. Про arduino digispark и ESP8266 , скоро будет статьиЦитата:
А про stm32 не будет ли полезных статеек. А то контроллер валяется без дела.
Нашёл мануалы, даже получилось прошить контроллер, помигал светодиодом : ) (STM 32)
Добрый день, пришла ручка фена, схема примерно такая. Как я понял зелёный это выход с геркона на контроллер. Вроде как положил ручку на подставку, и на контроллер пошёл сигнал к какому нибудь действию (спать например)Вложение 19352
В паяльной станции, сигнал с геркона служит сигналом снятия фена с подставки.
Фен не включится пока его с подставки не снимишь
Ну я так и сказал, только наоборот : ) Фен выключится на подставке.