Нужна помощь по коду
- Войдите на сайт для отправки комментариев
https://drive.google.com/open?id=1J7msbiW212aRUq0-mMXV2Me2uTB890Fm архив
#include "U8glib.h" // Библиотека дисплея
#include <FastPID.h> // Библиотека PID Регулятора
#include <CyberLib.h> // Библиотека для таймера
#include <RotaryEncoder.h> // Библиотека Энкодера
#include "GyverButton.h" // Библиотека кнопок
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
///////////////////////////////////////////////////////////////
#define ZER_PIN 2 // Pin Детектора нуля
#define SOL_PIN 3 // Pin MOSFET паяльника
#define FAN_PIN 11 // Pin MOSFET турбины
#define HOT_PIN 13 // Pin Нагревателя Фена
#define REL_PIN 12 // Pin Реле
#define BUZ_PIN 9 // Pin BUZZER
#define GER_PIN 8 // Pin Геркона
#define A_Pin 7 // Pin Энкодера А
#define B_Pin 6 // Pin Энкодера В
#define But_Pin 5 // Pin Энкодера Кнопки
///////////////////////////////////////////////////////////////
#define temp_sol A0 // Pin Операционного усилителя паяльника
#define temp_fan A1 // Pin Операционного усилителя Фена
//////////////////////////////////////////////////////////////
long interval = 100; // задержка обновления дисплея
float Delay_Sol = 300; // Задержка цикла поддержания температуры паяльника
float Delay_Fan = 300; // Задержка цикла поддержания температуры Фена
int solpoint = 200; // Начальное значение температуры паяльника
int hotpoint = 100; // Начальное значение температуры Фена
int fanpoint = 10; // Начальное значение Оборотов турбины
int min_temp_sol = 200; // Минимальное значение температуры паяльника
int max_temp_sol = 500; // Минимальное значение температуры паяльника
int min_temp_fan = 100; // Максимальное значение температуры паяльника
int max_temp_fan = 500; // Максимальное значение температуры паяльника
///////////////////////////////////////////////////////////////
int sol_raw = 0;
int fan_raw = 0;
int sol_set = 0;
int fan_set = 0;
int sol_tem_led = 0;
int hot_tem_led = 0;
int fan_tem_led = 0;
int result = 0;
int power = 0;
int i=0;
///////////////////////////////////////////////////////////////
long previousMillis = 0;
unsigned long currentMillis = 0;
unsigned long previousMil_Sol = 0;
unsigned long previousMil_Fan = 0;
volatile int tic, Dimmer;
unsigned long timing; // Переменная для хранения точки отсчета
/////////////PID sampling variables///////////////////////////
float Kp = 7.98, Ki = 0.055, Kd = 0.86, Hz = 10;
int output_bits = 8;
bool output_signed = false;
///////////// Переменные выборки АЦП//////////////////////////
int Current_Temp_Sol;
float Sol_temp_read;
#define ADC_MULT_SOL 5
#define ADC_MULT_SOL_SAMPLES (1 << ADC_MULT_SOL)
///////////////////////////////////////////////////////////////
int Current_Temp_Fan;
float Fan_temp_read;
#define ADC_MULT_FAN 5
#define ADC_MULT_FAN_SAMPLES (1 << ADC_MULT_FAN)
///////////////////////////////////////////////////////////////
RotaryEncoder encoder(A_Pin, B_Pin);
GButton butt1(But_Pin);
FastPID myPID(Kp, Ki, Kd, Hz, output_bits, output_signed);
///////////////////////////////////////////////////////////////
void setup(void)
{
TCCR1B = TCCR1B & 0b11111000 | 0x02; //кулер фена 24v. Частота ШИМ 11 и 3
pinMode(SOL_PIN, OUTPUT);
pinMode(FAN_PIN, OUTPUT);
pinMode(HOT_PIN, OUTPUT);
pinMode(REL_PIN, OUTPUT);
pinMode(GER_PIN, OUTPUT);
pinMode(BUZ_PIN, OUTPUT);
pinMode(temp_sol, INPUT);
pinMode(temp_fan, INPUT);
pinMode(ZER_PIN, INPUT);
butt1.setDebounce(50); // настройка антидребезга (по умолчанию 80 мс)
butt1.setTimeout(300); // настройка таймаута на удержание (по умолчанию 500 мс)
butt1.setType(HIGH_PULL); // HIGH_PULL - кнопка подключена к GND
butt1.setDirection(NORM_OPEN); // NORM_OPEN - нормально-разомкнутая кнопка
digitalWrite(SOL_PIN, LOW);
digitalWrite(HOT_PIN, LOW);
attachInterrupt(0, detect_up, FALLING); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень
StartTimer1(timer_interrupt, 40); // время для одного разряда ШИМ
StopTimer1();
Serial.begin(9600);
// Чтение пар-ов из EEPROM
//solpoint = EEPROM.read(1);
//hotpoint = EEPROM.read(2);
//fanpoint = EEPROM.read(3);
///////////////////////////////////////////////////////////////
}
static unsigned char tehnopageru[] {
0x00,0xC0,0x01,0x00,0x00,0xE0,0x07,0x00,0x00,0xE0,0x0F,0x00,0x00,0xF0,0x1F,0x00,
0x00,0xE0,0x3F,0x00,0x00,0xE0,0x3F,0x00,0x00,0xE0,0x3F,0x00,0x00,0xE0,0x7F,0x00,
0x00,0xC0,0x3F,0x00,0x00,0xC0,0x3F,0x00,0x00,0x80,0x3F,0x00,0x00,0x80,0x1F,0x00,
0x00,0x00,0x0F,0x00,0x00,0x8E,0x04,0x00,0x80,0x7F,0x00,0x00,0xC0,0x7F,0xF8,0x01,
0xE0,0xFF,0xFC,0x1F,0xE0,0xFF,0xFE,0x3F,0xE0,0x7F,0xFC,0x7F,0xF0,0x3F,0xFC,0x7F,
0xF0,0x1F,0xFC,0x7F,0xF0,0x1F,0xF8,0x3F,0xF0,0x0F,0xF0,0x1F,0xE0,0x07,0xE0,0x0F,
0xE0,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
////////////////////////////////////////////////////////////////
void disp()
{
u8g.drawXBM( 92, 5, 30, 30, tehnopageru);
u8g.drawLine(0,32,80,32);
u8g.drawLine(80,0,80,64);
u8g.setFont(u8g_font_10x20);
u8g.drawStr(2, 25, "SOL:");
if (sol_set == 0)
{
if(sol_raw == 0)
{
u8g.drawStr(45, 25, "OFF");
}
else
{
u8g.drawBox(45, 11, 30, 16);
u8g.setColorIndex(0);
u8g.drawStr(45, 25, "OFF");
u8g.setColorIndex(1);
}
}
else
{
u8g.setPrintPos(45, 25);
if(sol_tem_led == 0)
{
u8g.print(Current_Temp_Sol);
}
else
{
u8g.drawBox(45, 11, 30, 16);
u8g.setColorIndex(0);
u8g.print(solpoint);
u8g.setColorIndex(1);
}
}
u8g.drawStr(2, 55, "FAN:");
if(fan_set == 0)
{
if(fan_raw == 0)
{
u8g.drawStr(45, 55, "OFF");
}
else
{
u8g.drawBox(45,41, 30, 16);
u8g.setColorIndex(0);
u8g.drawStr(45, 55, "OFF");
u8g.setColorIndex(1);
}
}
else
{
u8g.setPrintPos(45, 55);
if (hot_tem_led == 0)
{
u8g.print(Current_Temp_Fan);
}
else
{
u8g.drawBox(45,41, 30, 16);
u8g.setColorIndex(0);
u8g.print(hotpoint);
u8g.setColorIndex(1);
}
}
u8g.setPrintPos(118, 55);
u8g.print("%");
if(fanpoint < 10)
{
u8g.setPrintPos(107, 55);
}
if(fanpoint > 9)
{
u8g.setPrintPos(97, 55);
}
if(fanpoint >99)
{
u8g.setPrintPos(87, 55);
}
u8g.print(fanpoint);
////////////////////////END_disp////////////////////
}
void control()
{
static int pos = 0;
int newPos = encoder.getPosition();
{
if (pos < newPos) result++;
if (pos > newPos) result--;
}
if(fan_set == 0 )
{
if (result > 2) result = 1;
if (result < 1) result =2;
}
else
{
if (result > 3) result = 1;
if (result < 1) result =3;
}
if (pos != newPos) pos = newPos;
if (result == 1)
{
sol_raw = 1;
}
else
{
sol_raw = 0;
}
if (result == 2)
{
fan_raw = 1;
}
else
{
fan_raw = 0;
}
if(result ==1 && power == 1)
{
sol_tem_led = 1;
solpoint = encoder.getPosition()*2;
}
else
{
sol_tem_led = 0;
}
if(result == 2 && power == 1)
{
hot_tem_led = 1;
hotpoint = encoder.getPosition()*2;
}
else
{
hot_tem_led = 0;
}
if (butt1.isClick()) power++;
if( power > 1) power = 0;
if (butt1.isClick()&&result == 1 && sol_set == 0)
{
sol_set = 1;
}
if (butt1.isClick()&&result == 2 && fan_set == 0)
{
fan_set = 1;
}
if (butt1.isStep()&&result == 1 && sol_set == 1)
{
sol_set = 0;
}
if (butt1.isStep()&&result == 2 && fan_set == 1)
{
fan_set = 0;
}
if(min_temp_sol >! solpoint){solpoint = min_temp_sol;}
if(max_temp_sol <! solpoint){solpoint = max_temp_sol;}
if(min_temp_fan >! hotpoint){hotpoint = min_temp_fan;}
if(max_temp_fan <! hotpoint){hotpoint = max_temp_fan;}
/////////////////////////////END_control/////////////////////////////////////////
}
void loop(void)
{
encoder.tick();
butt1.tick(); // обязательная функция отработки. Должна постоянно опрашиваться
currentMillis = millis();
///////////////////////ИЗТЕРЕНИЕ ТЕМПЕРАТУРЫ/////////////////////
if (currentMillis - previousMil_Sol >= Delay_Sol && sol_set == 1)
{
previousMil_Sol += Delay_Sol;
digitalWrite(SOL_PIN, LOW); // Отключаем MOSFET, чтобы мы могли прочитать термопару
Sol_temp_read = Read_Temp_Sol();
uint32_t before, after;
before = micros();
uint8_t output = myPID.step(solpoint, Sol_temp_read);
after = micros();
analogWrite(SOL_PIN, output);
}
if (currentMillis - previousMil_Fan >= Delay_Fan && fan_set == 1)
{
previousMil_Fan += Delay_Fan;
Fan_temp_read = Read_Temp_Fan();
uint32_t bef, aft;
bef = micros();
Dimmer = myPID.step(hotpoint, Fan_temp_read);
aft = micros();
}
////////////////////////////////////////////////////////////////////////////////////////////
if (digitalRead(GER_PIN) == LOW && Fan_temp_read > 100) //геркон замкнут, мигаем уст. температурой (ловим по земле)
{
analogWrite(FAN_PIN, 255);
digitalWrite(REL_PIN, LOW);
}
if (fan_set == 1 && (digitalRead(GER_PIN) == HIGH))
{
analogWrite(FAN_PIN, map(fanpoint, 1, 100, 120, 255));
digitalWrite(REL_PIN, HIGH);
}
if (fan_set == 0 && Fan_temp_read < 100)
{
analogWrite(FAN_PIN, 0);
digitalWrite(REL_PIN, LOW);
}
/////////// Вывод на дисплей /////////////////
if (millis() - timing > 500){
u8g.firstPage();
do { disp(); }
while( u8g.nextPage() );
timing = millis();
}
/////// Управление с помошью энкодера//////////
control();
////////////////END LOOP///////////////////////
}
//----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------
void timer_interrupt() { // прерывания таймера срабатывают каждые 40 мкс
tic++; // счетчик
if (tic > 255 - Dimmer && Dimmer != 0) // если настало время включать ток
digitalWrite(HOT_PIN, 1); // врубить ток
}
void detect_up() { // обработка внешнего прерывания на пересекание нуля снизу
tic = 0; // обнулить счетчик
ResumeTimer1(); // перезапустить таймер
attachInterrupt(0, detect_down, RISING); // перенастроить прерывание
}
void detect_down() { // обработка внешнего прерывания на пересекание нуля сверху
tic = 0; // обнулить счетчик
StopTimer1(); // остановить таймер
digitalWrite(HOT_PIN, 0); // вырубить ток
attachInterrupt(0, detect_up, FALLING); // перенастроить прерывание
}
//-----------------------ОБРАБОТЧИКИ ПРЕРЫВАНИЙ--------------------------
float Read_Temp_Sol()
{
// Фильтрация АЦП с помощью мультисэмплинга со значениями, определенными в начале
int adc = 0;
for (int i = 0; i < ADC_MULT_SOL_SAMPLES; ++i)
adc += analogRead(temp_sol);
adc = adc >> ADC_MULT_SOL;
// Получаем уравнения линейной регрессии из данных excel (Graph adc / temperature) (вам необходимо выполнить реальные измерения с помощью внешнего термометра)
double temp_sol = 0.9241 * adc - 51.146;
// Дополнительная фильтрация
Current_Temp_Sol += (temp_sol - Current_Temp_Sol) * 0.05;
return (Current_Temp_Sol);
}
float Read_Temp_Fan()
{
// Фильтрация АЦП с помощью мультисэмплинга со значениями, определенными в начале
int adc = 0;
for (int i = 0; i < ADC_MULT_SOL_SAMPLES; ++i)
adc += analogRead(temp_fan);
adc = adc >> ADC_MULT_FAN;
// Получаем уравнения линейной регрессии из данных excel (Graph adc / temperature) (вам необходимо выполнить реальные измерения с помощью внешнего термометра)
double temp_fan = 0.9241 * adc - 51.146;
// Дополнительная фильтрация
Current_Temp_Fan += (temp_fan - Current_Temp_Fan) * 0.05;
return (Current_Temp_Fan);
}
вас "не хватает" даже прочитать правила форума, прежде чем постить.
По сути вопроса - написать экранное меню - это приличный обьем работы. Крайне маловероятно, что кто-то будет делать это для вас в свое свободное время...
Зачем Вам этот "гемморой"? Продаются готовые наборы "паяльная станция на Ардуино", они в т.ч. входили в этом году в соревнования World Skills Juniour в категории 12-14лет (6-7кл).. дитенок из нашей школы с ним занял 3-е место на отборочных ..
в данной конфигурации T12 +фен на одном мк, нет ни одного проекта. И аппаратно проект готов
И аппаратно проект готов
Ну, а на то, чтобы почитать правила форума и вставить код по правилам у Вас времени нет?
Я не когда не читал форумы и тем более не чего не постил. Всегда разбрался сам.
Ну, значт, и дальше не отступай от традицый. Разбирайся сам.
Я и занимаюсь этим.
Я не когда не читал форумы
Значит, правила форума не читаем и не выполняем из принципиальных соображений? :) Ну, тогда продолжайте разбираться самостоятельно. Оно и полезнее.
Если у вас жопа горит от каждого не правильного оформленного поста, может тогда перестанете их вовсе комментировать и обращать на них внимание.
Если у вас жопа горит от каждого не правильного оформленного поста, может тогда перестанете их вовсе комментировать и обращать на них внимание.
а зачем тогда вообще ваши посты нужны?
Поймите. разбираться в неправильно выложенном коде НИКТО НЕ СТАНЕТ. Если вам хочется покачать права - выберите себе другой форум.
Код БЕЗ НОМЕРОВ СТРОК никто смотреть НЕ будет. Неужели непонятно зачем "правильно" вставлять код? Или нам писать, ошибка в строке #ХЗ ? Или пальцами сверху отсчитывать?
Ты, наерна ОЧЕНЬ сильный зато.
Я не отрицаю что не правильно оформил пост, я хотел переделать его, но зачем хейтить не знающего человека, как вообще пользоваться форумом.
но зачем хейтить не знающего человека, как вообще пользоваться форумом.
Для хайпа, вестимо.
Я не отрицаю что не правильно оформил пост, я хотел переделать его, но зачем хейтить не знающего человека, как вообще пользоваться форумом.
переделали бы сразу - никто бы и не хейтил. А когда человек поступает неправильно и начинает вместо исправлений права качать - таких никто не любит.
Я это прекрасно понимаю, и свои ошибки, извините если я кого-то зацепил.
можно отредактировать ветку ?
можно отредактировать ветку ?
если вы про скетч - первый пост ветки отредактировать нельзя. поэтому просто выложите код новым постом.
Но дальше почитайте то, что я вам писал в своем первом ответе. Кроме правильности выклдывания кода - второе замечание остается справедливым. Чудес не ждите.
Графическая оболочка написана, только вот управление этой графической оболочкой
не могу дописать, только через костыли получается,
функция control () -это управление ей. disp () - оболочка
код без библиотеки дисплея работает шустро, как нужно. как только вставляю часть кода дисплея и библиотеку начинается не понятно что.
Ваша главная ошибка, как я вижу - вы при каждом проходе loop заново перерисовываете все на дисплее - логотип, все линии и надписи - даже если ни одна цифра не изменилась. Совершенно неудивительно, что все дико тормозит.
Вам нужно разделить процедуру вывода на дисплей на две части. В первой вы выводите на дисплей все элементы офрмления - линии, надписи, картинки. Во второй - только параметры - температуру паяльника, мощность фена... что там еще...
В начале программы вы запускаете обе процедуры. А потом - только вторую, обновляя лишь те элементы картинки, которые реально изменились. И делать это нужно не при каждом вызове цикла loop. а только при изменении параметров.
Так я понял. если говорить про первую часть, то можно ее запихать в setup() ?
Так я понял. если говорить про первую часть, то можно ее запихать в setup() ?
если у вас нет многостраничных меню - то можно. Но меня смущают строчки 333 и 337 - там какие-то страницы упоминаются (не особо знаком с библиотекой U8Glib)
Стр. 005 не смущает? ;)
Я сам знаком плохо с этой библиотекой, но в примере так было, я решил так и использовать, так как не компилиться без этого
Стр. 005 не смущает? ;)
не заметил :)
В чужом коде блох искать - хуже нет проклятия!
--------------
Я вот два дна старый сервер перетаскивал на новый комп. Сервер написан в 2007. Частично переделан на php 5.4? сейчас. - 7.2, если что.
Среди нас много представителей ненавистной Веб-профессии...так вот для понимающих: сайт написан в переходный период: ;)))))
Частично mysql, частично mysqli, частично ereg частично preg. Млиииин! Человек, который это писал, слово ООП, произносит только по слогам, поэтому повторяющегося кода - сотни строк и десятки блоков! И в каждом руками нужно править.... В старое время теги <? .... ?> - прокатывали, теперь только <?php ..... ?>. Ну и все в таком духе. Через два дня я всё запустил, но очень хотелось... и до сих пор хочется, кого-нибудь ме-еедленно убить.
===================
И тут читаю на форуме, что человек хочет найти кого-то для копания в чужом мусоре! ;)))) Ох... как же мне вас не хватало! (с)
Подскажите паяльную станцию т12 и фен атмеге получилось запустить?
можно исходники скинуть кода и схемы?
А то архив не рабочий