Skip to content

Instantly share code, notes, and snippets.

@XanderEVG
Created November 11, 2018 15:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XanderEVG/bc1cfcbb97258c68d6af6fe3c78ad9f5 to your computer and use it in GitHub Desktop.
Save XanderEVG/bc1cfcbb97258c68d6af6fe3c78ad9f5 to your computer and use it in GitHub Desktop.
DIHALT_RTOS_EXAMPLE
//============================================================================
// Прерывания
//============================================================================
ISR(RTOS_TIMER_ISR)
{
TimerService(); //Магия таймерной службы
}
//Прерывание опроса кнопки
ISR (PCINT2_vect)
{
byte buttonState = HARD_BTN_PORT & 1<<HARD_BTN_PIN;
if(!buttonState)
{
if(_btn_state==BTN_NO_PRESS)
{
_btn_state=BTN_PRESS;
SetTask(Btn_pressed);
// Дребезг контактов не влияет,
// т к SetTask не добавляет задачу,
// если она уже в очереди.
// Но можно взводить запрет прервывания на этот пин, а
// в Btn_pressed или Btn_release обратно разрешать прерывание
// Фишка: в обработке кнопок можно писать тяжелые функции,
// выполняться будет вне прерывания
}
}
}
//============================================================================
// Область задач
//============================================================================
void BlinkON (void)
{
digitalWrite(LED_BUILTIN, HIGH);
SetTimerTask(BlinkOFF,500);
}
void BlinkOFF (void)
{
digitalWrite(LED_BUILTIN, LOW);
SetTimerTask(BlinkON,500);
}
void Btn_pressed()
{
Play();
SetTimerTask(Btn_release,300);
}
void Btn_release()
{
// нужно что бы не обрабатывать нажатия кнопок чаще чем 1 раз в 300мс
_btn_state=BTN_NO_PRESS;
}
void read_max_volume()
{
//в прерывание выносить лень, ресурсов хватает что бы юзать тупую analogRead
int val;
val = analogRead(MAX_VOLUME_PIN);
val = map(val, 0, 1023, 0, 30);
val = constrain(val, 0, 30);
max_sound_lvl=val;
SetTimerTask(read_max_volume, READ_MAX_VOLUME_DELAY);
}
void check_time()
{
cli();
//_time_h - это переменные из прерывания, поэтому оборачиваем в cli/sei
byte time_h=_time_h;
byte time_m=_time_m;
byte time_s=_time_s;
sei();
#if defined( CHECK_TIME_SHOW_TIME ) && defined( BLUETOOTH_BY_SOFT )
Serial.print(time_h, DEC);
Serial.print(":");
Serial.print(time_m, DEC);
Serial.print(":");
Serial.println(time_s, DEC);
#endif
if(время_позднее) Включаем тихий режим;
SetTimerTask(check_time, 1000);
}
void sync_send_data()
{
// Пакет состоит из 4 частей:
// "SYNC_" - начало пакета, 4 байта
// Method - тип сообщения, 1 байт.
// DATA - данные в виде строки, около 31 байт
// "END\n" - конец пакета
SerialBT.print("SYNC_D"); // старт
SerialBT.print("D"); //метод
SerialBT.print("полезная инфа"); //данные
SerialBT.print("END\n"); // конец. println почему то не подходит, видать отправляет \r\n или подобное
}
void sync_get_data(byte *data)
{
читаем_данные_из_пакета();
if(ошибка)
{
SetTask(sync_send_error);
}
else
{
SetTask(after_sync); //сохраняем и настраиваем mp3 модуль
}
}
void after_sync()
{
SetTask(write_rtc);
SetTask(sync_eeprom_update);
SetTask(write_rtc);
SetTask(setting_mp3);
SetTask(sync_send_ok);
}
void check_sync()
{
// Проверка пришло ли сообщение от блютуза
// Ждем пока пакет придет целиком
if (SerialBT.available() > 40) {
for(byte i=0; i<41; i++)
{
data_array[i]=SerialBT.read();
}
//Проверяем начало пакета, ищем "SYNC_", если не нашли это в начале пакета - пакет битый
for(byte i=0; i<5; i++)
{
if(data_array[i]!=start_str[i])
{
error("Не нашли начало пакета");
}
}
// Если нашли начало пакета - ищем конец пакета. если не нашли - ну ты понел
if(correct_string!=false)
{
byte end_str_index=3;
for(byte i=40; i>36; i--)
{
if(data_array[i]!=end_str[end_str_index])
{
error("Не нашли конец пакета");
}
end_str_index--;
}
}
//Если начало и конец пакета найдены - смотрим какой метод пришел
if(correct_string!=false)
{
byte method = data_array[SYNC_INDEX_METHOD];
if(method=='R') // - запрос анных, отправляем
{
SetTask(sync_send_data);
}
else if(method=='W') //Пришли новые данные - читаем и сохраняем
{
sync_get_data(data_array);
}
else if(method=='T') //Пришло время
{
sync_get_time(data_array);
}
else if(method=='P') //Пришла команда воспроизвести мелодию
{
sync_play();
}
else
{
error("че за метод?!")
}
}
}
SetTimerTask(check_sync, SYNC_PERIOD);
}
//********************************************************************************************************************************************************
// ************************* Главный цикл //**************************************************************************************************************
//********************************************************************************************************************************************************
void setup() {
поднимаем_serial();
настраиваем_пины();
инициализируем_переменные();
настраиваем_mp3();
настраиваем_прерывание_с_кнопки(PCIN2);
настраиваем_таймер_для_отсчета_времени();
InitRTOS(); // Инициализируем ядро таймерной службы
RunRTOS(); //Запускаем таймерную службу и диспетчер задач
// Запуск фоновых задач
SetTimerTask(read_max_volume, READ_MAX_VOLUME_DELAY);
SetTimerTask(check_time, 1000);
SetTimerTask(read_rtc, RTC_READ_PERIOD);
SetTimerTask(check_sync, SYNC_PERIOD);
SetTimerTask(BlinkON,500);
sei();
}
void loop() {
TaskManager();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment