Форум обсуждения систем  

Вернуться   Форум обсуждения систем "Умный дом", проектов Ардуино, OpenWRT и других DIY устройств > Форум умного дома > Сделай сам > CyberWrt

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.05.2016, 01:15   #281
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,616
Вес репутации: 9820
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию Re: CyberWrt модуль "AquaLog"

Тогда PCINT
Admin вне форума   Ответить с цитированием
Старый 18.06.2016, 23:16   #282
Tohin
Moderator
 
Регистрация: 20.07.2014
Адрес: МСК
Сообщений: 991
Вес репутации: 1030
Tohin is a jewel in the roughTohin is a jewel in the roughTohin is a jewel in the rough
По умолчанию Re: CyberWrt модуль "AquaLog" (PCINT версия)

Ну вот.. "всего лишь" за месяц я научился считать импульсы. Сбоев вроде бы нет. Точнее есть: при использовании кнопок, при недостаточном усилии, бывает неустойчивый контакт. от этого многократные срабатывания. Надеюсь, что на герконах такого не будет.

Также предполагаю, что тут не паханное поле для оптимизации.

Ну и вот он. Счетчик импульсов на PCINT:

PHP код:
/* Pin to interrupt map:
  D0-D7 = PCINT 16-23 = PCIR2 = PD = PCIE2 = pcmsk2
  D8-D13 = PCINT 0-5 = PCIR0 = PB = PCIE0 = pcmsk0
  A0-A5 (D14-D19) = PCINT 8-13 = PCIR1 = PC = PCIE1 = pcmsk1
  Я собираюсь использовать PB0 (холодная) PB1 (горячая). это пины 8 и9 на плате UNO
  При вызове обработчика любого прерывания бит глобального разрешения прерываний I регистра SREG (status register - регистр состояния) сбрасывается в "0"и только по завершении обработки прерывания снова устанавливается в "1"
  и разрешает начать обработку следующего прерывания в очереди.
  Чтобы установить ручками этот бит существует функция sei(), а чтобы сбросить - cli().
  При запуске программы этот бит всегда сброшен и чтобы прерывания срабатывали его нужно установить (вызвать sei()).
  к выводам 8 и 9 ардуины (PortB0 и 1) подключены через кнопки к +5, со стороны пинов подтянуты резисторами к земле
*/
#include <avr/interrupt.h>

volatile uint16_t Hot_CountCold_Count;
uint16_t HotColdview;

void setup() {
  
  
PCICR 0b00000001// включаем прерывания PCINT0. цитата из даташита Bit 0 – PCIE0: Pin Change Interrupt Enable. Any change on any enabled PCINT[7:0] pin will cause an interrupt.
  
DDRB 0b00111100// пины 0 и 1 порта B - это входы, все остальное - выходы.
  
PORTB 0x00;  // отключаем подтяжку на всех пинах. входы 0 и 1 подтянуты к земле через резистор,и к +5v через кнопку.
  
PCMSK0 0b00000011// Создаем маску для PCINT0, чтобы реагировать только на пины 0 и 1. Т.к. на остальных могут быть релешки и не нужно дергать прерыывание при их срабатывании.
  
sei();
  
Serial.begin(9600);
 
Serial.print("I'm ready\n\r"); //Для отладки, пишем что ардуинка жива.


}


ISR(PCINT0_vect) { // Кто-то дернул прерывание на portb

  
if ((PINB & (<< PB0)) == && Cold_Count == 0) { //Если это PB0(8 пин), то нужно добавить 10л к холодной воде. второй частью проверяем, что мы это срабатывание еще не учитывали.
    
Cold_Count 1// сообщаем в основной цикл, что было срабатывание геркона на холодной воде.
  
}
  if ((
PINB & (<< PB0)) == && Cold_Count == 2) { //Если это PB0(8 пин) перешел в ноль и при этом стоит флаг состояния "учтено", то нужно обнулить флаг, для последующего учета, при переходе в еденицу
    
Cold_Count 0

  }
  if ((
PINB & (<< PB1)) == && Hot_Count == 0) { //Если это PB1(9 пин), то делаем то же самое с горячей водой.
    
Hot_Count 1;
  }
  if ((
PINB & (<< PB1)) == && Hot_Count == 2) { 
    
Hot_Count 0;
  }

}

void loop() {
  
// put your main code here, to run repeatedly:

  
if ( (millis() % 500) == 0) { //каждые 500мс проверяем, что нам нужно посчитать. Т.к. считаем мы  один раз в полсекунды - дрябезг нам не страшен.
    
if (Cold_Count == 1) { //если надо посчитать холодную воду
      
Cold += 10//добавляем к счетчику холодной воды 10л.
      
Cold_Count 2//ставим флаг в состояние "учтено"
      
view 1;

    }
    if (
Hot_Count == 1) { // то же самое для горячей воды
      
Hot += 10;
      
Hot_Count 2;
      
view 1;
    }
  }
  if ( 
view == 1) {
    
Serial.print("Hot: ");
    
Serial.print(Hot);
    
Serial.print("\n\r");
    
Serial.print(" Cold: ");
    
Serial.println(Cold);
    
Serial.print("\n\r");
    
view 0;
  }

Желающие могут адаптировать его под модуль аквалог. а я буду думать над передачей данных по clunet.
Tohin вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 3 (пользователей: 0 , гостей: 3)
 
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 13:57. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Яндекс.Метрика