コード例 #1
0
ファイル: tastdimmer.c プロジェクト: hcanchristian/openHCAN
void tastdimmer_can_callback(device_data_tastdimmer *p, const canix_frame *frame)
{

	if (tastdimmer_is_in_group(p, frame->data[2]))
	{
		switch (frame->data[1])
		{
			case HCAN_HES_TASTER_DOWN :
				darlingtonoutput_setpin(p->config.port, 1);
				break;
			case HCAN_HES_TASTER_UP :
				darlingtonoutput_setpin(p->config.port, 0);
				break;
		}
	}
}
コード例 #2
0
ファイル: usvstatemachine.c プロジェクト: hcanIngo/openHCAN
void switch_to_battery(void)
{
	canix_frame message;

	// Status merken:
	on_battery = 1;


	// Relais schalten
	darlingtonoutput_setpin(7,1);

	// Timer auf 2 Sekunden setzen, d.h. fruehstens in
	// 2 Sekunden kann die USV wieder reagieren. Das ist noetig
	// damit kein "Prellen" oder "Flackern" passiert
	usv_timer = 200;

	// LEDs anpassen:
	led_set(3,0);
	led_set(6,10);

	// Busteilnehmer informieren:
	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_INFO;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_USVS;
	message.data[1] = HCAN_USVS_STATE_INFO;
	message.data[2] = on_battery;
	message.size = 3;
	canix_frame_send(&message);
}
コード例 #3
0
ファイル: usvstatemachine.c プロジェクト: hcanIngo/openHCAN
void switch_to_netzbetrieb(void)
{
	canix_frame message;

	// Status merken:
	on_battery = 0;

	// Relais schalten
	darlingtonoutput_setpin(7,0);

	// Auch hier wieder: ein Prellen verhindern
	usv_timer = 10;

	// LEDs anpassen:
	led_set(3,10);
	led_set(6,0);

	// Busteilnehmer informieren:
	message.src = canix_selfaddr();
	message.dst = HCAN_MULTICAST_INFO;
	message.proto = HCAN_PROTO_SFP;
	message.data[0] = HCAN_SRV_USVS;
	message.data[1] = HCAN_USVS_STATE_INFO;
	message.data[2] = on_battery;
	message.size = 3;
	canix_frame_send(&message);
}
コード例 #4
0
ファイル: heizung.c プロジェクト: hcanchristian/openHCAN
/**
 * this one cares about the PWM (pulse width modulation) for 
 * achieving heating rates between off and on 
 */
void heizung_handle_pwm(device_data_heizung *p)
{
	if (++p->pwm_counter >= (p->pwm_end))
	{
		p->pwm_counter = 0;
		darlingtonoutput_setpin(p->config.port, 1);
	}

	if (p->pwm_counter >= p->pwm_width)
	{
		darlingtonoutput_setpin(p->config.port, 0);
	}
	/*
	canix_syslog_P(SYSLOG_PRIO_DEBUG,
			PSTR("handle_pwm: heiz: %d: %d"), p->config.id, 
			darlingtonoutput_getpin(p->config.port));
	*/
}
コード例 #5
0
ファイル: heizung.c プロジェクト: hcanchristian/openHCAN
/**
 * this timer handler is called every second
 */
void heizung_timer_handler(device_data_heizung *p)
{
	if (p->ventilpflege_counter > 0)
		p->ventilpflege_counter--;

	// Ventilpflege aktivieren, falls der richtige Zeitpunkt dazu ist:
	heizung_check_ventilpflege(p);

	if (p->received_interval_counter != 0xff)
		p->received_interval_counter++;

	heizung_handle_pwm(p);

	if (p->duration_counter > 0)
	{
		p->duration_counter -= 1;
		if (p->duration_counter == 0)
		{
			// Zeit ist abgelaufen; nun wieder auf Automatik-Modus
			// stellen:
			//
			p->mode = HEIZUNG_MODE_AUTOMATIK;
		}
	}

	if (p->reed_heiz_stop_counter > 0)
	{	
		p->reed_heiz_stop_counter -= 1;

		if (p->reed_heiz_stop_counter == 0)
		{
			canix_syslog_P(SYSLOG_PRIO_DEBUG,
					PSTR("heiz-stop ende (heizung %d)"), p->config.id);
		}
	}

	/*
	 * Schaltet die HK-Ventile aus, wenn ein Heizstop vorliegt. Dies passiert
	 * in regelmaessigen Abstaenden, da eventuell aufgrund der Heizsteuerlogik
	 * die PWM nicht regelmaessig upgedatet wird und so das HK-Ventil nicht auf
	 * den Reedkontakt reagiert.
	 */
	heizung_update_heizstop(p);

	if (p->timer_counter++ >= 5)
	{
		p->timer_counter = 0;

		switch (p->mode)
		{
			case HEIZUNG_MODE_OFF : 
				{
					if (p->ventilpflege_counter)
					{
						// Sonderfall: Ventilpflege ist aktiv; dazu
						// Ventil einschalten, sonst aber nichts
						// unternehmen:
						
						p->manual_rate = 0;

						// Ventil einschalten:
						heizung_set_pwm(p,100);
						darlingtonoutput_setpin(p->config.port, 1);

						canix_syslog_P(SYSLOG_PRIO_DEBUG, 
								PSTR("ventilpflege: 1"));
					}
					else
					{
						// das ist Normalfall: keine Ventilpflege aktiv.
						p->manual_rate = 0;
						heizung_set_pwm(p,0);

						// Ventil ausschalten, falls es an ist:
						if (darlingtonoutput_getpin(p->config.port))
							darlingtonoutput_setpin(p->config.port, 0);
					}
					return;
				}
			case HEIZUNG_MODE_MANUAL :
				{
					heizung_set_pwm(p, p->manual_rate);
				}
				break;
			case HEIZUNG_MODE_AUTOMATIK :
				{
					// Wenn ein gueltiger Messwert vorliegt
					// (d.h. wenn innerhalb eines definierten Zeitraumes
					// ein Sensor-Messwert eingetroffen ist:
					if (p->received_interval_counter < 255)
					{
						int8_t index;
						index = heizung_get_matching_zeitzone_index(p);
						if (index != -1)
						{
							// we got an zeitzone which matches
							solltemp_line_t *solltemp_line = (solltemp_line_t*) 
								&(p->config.zeitzone0_id);
							heizung_set_pwm_by_temp(p, 
									solltemp_line[index].temp,
									p->measure_value);
						}
						else
						{
							// keine passende Zeitzone gefunden
							heizung_set_pwm(p,0);
						}
					}
					else
					{
						canix_syslog_P(SYSLOG_PRIO_ERROR, 
								PSTR("keine Sensor-Messwerte vorhanden!"));
					}
				}
				break;
			case HEIZUNG_MODE_THERMOSTAT :
				{
					// Wenn ein gueltiger Messwert vorliegt
					// (d.h. wenn innerhalb eines definierten Zeitraumes
					// ein Sensor-Messwert eingetroffen ist:
					if (p->received_interval_counter < 255)
					{
						heizung_set_pwm_by_temp(p, p->thermostat_temp,
								p->measure_value);
					}
					else
					{
						canix_syslog_P(SYSLOG_PRIO_ERROR, 
								PSTR("keine Sensor-Messwerte vorhanden!"));
					}
				}
				break;
		}
	}

	// Waermebedarfsmeldung versenden:
	if (p->waermebedarf_counter-- == 0)
	{
		canix_frame message;

		// Waermebedarfsmeldungen alle 60 Sekunden
		p->waermebedarf_counter = 60;

		// den aktuellen Ventilstand / Heizrate ermitteln:
		uint8_t rate = heizung_get_pwm(p);

		// Feature-Bit testen, und ggfls Waermebedarf verdoppeln:
		if (p->config.feature & (1<<HEIZUNG_FEATURE_DOPPEL_WAERMEBEDARF))
			rate = rate << 1;

		// Der Waermebedarf ist proportional zur Ventilstellung, d.h.
		// der Bedarf ist hoch, wenn das Ventil voll offen ist, und ist
		// nicht vorhanden, wenn das Ventil zu ist.

		message.src = canix_selfaddr();
		message.dst = HCAN_MULTICAST_INFO;
		message.proto = HCAN_PROTO_SFP;
		message.data[0] = HCAN_SRV_HES;
		message.data[1] = HCAN_HES_HEIZUNG_WAERMEBEDARF_INFO;
		message.data[2] = p->config.id;
		message.data[3] = rate;
		message.size = 4;

		canix_frame_send_with_prio(&message, HCAN_PRIO_LOW);
	}
}
コード例 #6
0
// hier werden die anstehenden Rolladenauftraege jede 10-tel Sekunde verarbeitet/angestossen
inline void rolladen_timer_handler(device_data_rolladen *p, uint8_t zyklus)
{
	if (zyklus != 10) return; // 10tel-Sekunden-Zyklus verwendet

	//// Im 2-Taster-Betrieb manuell die Kalibrierung anstossen:
	if (p->long_pressed_counter > 0)  p->long_pressed_counter--;
	else if (p->long_pressed_counter == 0)
	{
		prepare_calibration (p); // kalibrieren per Taster-"ZU" oder "AUF"
		p->long_pressed_counter = -1; // abmelden
	}

	//// Richtungswechsel im 1-Taster-Betrieb:
	if (p->change_dir_counter > 0)  p->change_dir_counter--;
	else if (p->change_dir_counter == 0)
	{
		p->last_dir = !p->last_dir; // Richtungswechsel
		p->change_dir_counter = -1; // abmelden
	}


	//// Soll-/Endlage-Pruefung und ggf. Abschaltung:
	if (p->power && p->soll_power) // Rolladen faehrt und hat keinen Halt-Auftrag?
	{
		if(ROLLADEN_DIR_AB == p->dir)
		{
			p->laufzeit--; // Rolladen faehrt runter
			if (p->laufzeit <= p->soll_laufzeit) rolladen_cmd_stop (p); // Halt-Auftrag durch das Erreichen der Soll-Lage
		}
		else // AUF:
		{
			p->laufzeit++; // Rolladen faehrt hoch
			if (p->laufzeit >= p->soll_laufzeit) rolladen_cmd_stop (p); // Halt-Auftrag durch das Erreichen der Soll-Lage
		}

		p->summe_laufzeit++; // fuer die Kalibrierung
	}



	//// Relais-Blocking:
	if (p->blockingTimer) p->blockingTimer--; // Blockierung aktiv
	else
	{
		if (p->soll_power) p->exe_power = 1; // Fahr-Auftrag: Power-Relais darf nun eingeschaltet werden
		else p->exe_dir = 1; // Halt-Auftrag: Dir-Relais darf nun umgeschaltet werden
	}


	//// Relais-Execution:
	if (p->exe_dir && (p->dir != p->soll_dir)) // Aenderung?
	{
		darlingtonoutput_setpin(p->config.port_dir, p->soll_dir);
		p->dir = p->soll_dir; // Relais nur bei Aenderung ansteuern
		p->exe_dir = 0; // Default: Relais nicht ansprechen
	}

	if (p->exe_power && (p->power != p->soll_power)) // Aenderung?
	{
		darlingtonoutput_setpin(p->config.port_power, p->soll_power);
		p->power = p->soll_power; // Relais nur bei Aenderung ansteuern
		p->exe_power = 0; // Default: Relais nicht ansprechen
	}

	if (p->power) p->stoppuhr++;
}