17 #include <avr/interrupt.h> 18 #include <util/delay.h> 40 uint8_t sendRegData[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
42 bool laden =
false, last =
false, vent_1 =
false, vent_2 =
false;
43 int aktuelle_zelle_P1 = 4, aktuelle_zelle_P2 = 0;
48 int einlese_zeit[2] = { 0x00, 0x00 };
49 float charge[8] = { 600, 600, 600, 600, 600, 600, 600, 600 };
51 int16_t c_max[8] = { 750, 750, 750, 750, 750, 750, 750, 750 };
52 int SOC[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
53 int SOH[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
54 float ladezyklus[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
55 bool flag_tcrit[8] = {
false,
false,
false,
false,
false,
false,
false,
false };
56 bool flag_tupper[8] = {
false,
false,
false,
false,
false,
false,
false,
false };
57 bool flag_tlower[8] = {
false,
false,
false,
false,
false,
false,
false,
false };
58 bool akku_an[8] = {
false,
false,
false,
false,
false,
false,
false,
false };
59 bool reset_eingabe[8] = {
false,
false,
false,
false,
false,
false,
false,
false };
60 bool akku_laden[8] = {
false,
false,
false,
false,
false,
false,
false,
false };
61 bool akku[8] = {
false,
false,
false,
false,
false,
false,
false,
false };
62 bool entlade_start =
false;
63 bool usb_versorgung =
false;
64 float voltage_rechnen[8][5];
65 uint8_t max_volt = 0, min_volt = 0;
66 float gesamt_volt = 0.00;
67 uint32_t betriebszeit_s[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
68 uint32_t ladezeit_s[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
69 uint8_t state_counter = 0;
70 int h[8][2], m[8][2], s[8][2];
72 void lade_steuerung (
void )
114 void entlade_steuerung (
void )
118 leerlauf_voltage_get_data ();
144 messwert_flag =
true;
149 temperatur_entladen ();
151 if ( entlade_start || last )
153 else if ( voltage[aktuelle_zelle_P1] < VOLTAGE_LOW || voltage[aktuelle_zelle_P2] < VOLTAGE_LOW ) akkuauswahl ();
155 terminal_usb_ausgabe ();
163 void leerlauf_steuerung (
void )
168 leerlauf_voltage_get_data ();
170 messwert_flag =
true;
179 if ( state_counter >= 6 )
186 void control_check (
void )
199 leerlauf_voltage_get_data ();
200 for (
int i = 0; i <= 7; i++ )
202 if ( voltage[i] > 1 )
208 if ( PORTD_IN & LADE_POWER_IN_INT_bm )
212 mosfet_notstrom ( NOTSTROM_AUS );
214 else if ( PORTD_IN & USB_POWER_IN_INT_bm )
216 usb_versorgung =
true;
218 mosfet_notstrom ( NOTSTROM_AUS );
223 usb_versorgung =
false;
224 entlade_start =
true;
230 betriebsart = LEERLAUF;
233 void temperatur_entladen (
void )
236 static int kritische_temp[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
237 static int kritischer_durchlauf[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
239 for (
int sensor_nummer = 0; sensor_nummer <= 3; sensor_nummer++ )
243 if ( !flag_tupper[sensor_nummer] )
246 for (
int sensor = 0; sensor <= 3; sensor++ )
248 if ( !flag_tupper[sensor] ) t_norm++;
250 if ( t_norm == 4 )
ventilator ( MOSFET_VENT1, VENT_AUS );
252 else if ( flag_tcrit[sensor_nummer] )
254 if ( akku[sensor_nummer] )
261 if ( kritischer_durchlauf[sensor_nummer] >= 2 )
263 if ( temp[sensor_nummer] >= kritische_temp[sensor_nummer] )
265 kritischer_durchlauf[sensor_nummer] = 0;
266 kritische_temp[sensor_nummer] = 0.00;
271 kritischer_durchlauf[sensor_nummer]++;
274 else if ( flag_tupper[sensor_nummer] )
276 if ( akku_an[sensor_nummer] )
285 if ( flag_tcrit[sensor_nummer] )
287 kritische_temp[sensor_nummer] = temp[sensor_nummer];
288 kritischer_durchlauf[sensor_nummer] = 0;
291 else if ( flag_tupper[sensor_nummer] )
298 for (
int sensor_nummer = 4; sensor_nummer <= 7; sensor_nummer++ )
302 if ( !flag_tupper[sensor_nummer] )
305 for (
int sensor = 0; sensor <= 3; sensor++ )
307 if ( !flag_tupper[sensor] ) t_norm++;
309 if ( t_norm == 4 )
ventilator ( MOSFET_VENT2, VENT_AUS );
311 else if ( flag_tcrit[sensor_nummer] )
313 if ( akku[sensor_nummer] )
320 if ( kritischer_durchlauf[sensor_nummer] >= 2 )
322 if ( temp[sensor_nummer] >= kritische_temp[sensor_nummer] )
324 kritischer_durchlauf[sensor_nummer] = 0;
325 kritische_temp[sensor_nummer] = 0.00;
330 kritischer_durchlauf[sensor_nummer]++;
333 else if ( flag_tupper[sensor_nummer] )
335 if ( akku_an[sensor_nummer] )
344 if ( flag_tcrit[sensor_nummer] )
346 kritischer_durchlauf[sensor_nummer] = 0;
347 kritische_temp[sensor_nummer] = temp[sensor_nummer];
350 else if ( flag_tupper[sensor_nummer] )
358 void temperatur_laden (
void )
361 static int kritische_temp[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
362 static int kritischer_durchlauf[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
364 for (
int sensor_nummer = 0; sensor_nummer <= 3; sensor_nummer++ )
368 if ( !flag_tupper[sensor_nummer] )
371 for (
int sensor = 0; sensor <= 3; sensor++ )
373 if ( !flag_tupper[sensor] ) t_norm++;
375 if ( t_norm == 4 )
ventilator ( MOSFET_VENT1, VENT_AUS );
377 else if ( flag_tcrit[sensor_nummer] )
379 if ( kritischer_durchlauf[sensor_nummer] >= 2 )
381 if ( temp[sensor_nummer] >= kritische_temp[sensor_nummer] )
383 kritischer_durchlauf[sensor_nummer] = 0;
384 kritische_temp[sensor_nummer] = 0.00;
389 kritischer_durchlauf[sensor_nummer]++;
394 if ( flag_tcrit[sensor_nummer] )
396 kritischer_durchlauf[sensor_nummer] = 0;
397 kritische_temp[sensor_nummer] = temp[sensor_nummer];
400 else if ( flag_tupper[sensor_nummer] )
407 for (
int sensor_nummer = 4; sensor_nummer <= 7; sensor_nummer++ )
411 if ( !flag_tupper[sensor_nummer] )
414 for (
int sensor = 4; sensor <= 7; sensor++ )
416 if ( !flag_tupper[sensor] ) t_norm++;
418 if ( t_norm == 4 )
ventilator ( MOSFET_VENT2, VENT_AUS );
420 else if ( flag_tcrit[sensor_nummer] )
422 if ( kritischer_durchlauf[sensor_nummer] >= 2 )
424 if ( temp[sensor_nummer] >= kritische_temp[sensor_nummer] )
426 kritischer_durchlauf[sensor_nummer] = 0;
427 kritische_temp[sensor_nummer] = 0.00;
432 kritischer_durchlauf[sensor_nummer]++;
437 if ( flag_tcrit[sensor_nummer] )
439 kritischer_durchlauf[sensor_nummer] = 0;
440 kritische_temp[sensor_nummer] = temp[sensor_nummer];
443 else if ( flag_tupper[sensor_nummer] )
452 void akkuauswahl (
void )
454 float akku_voltage_P1 = 0.00, akku_voltage_P2 = 0.00;
455 float max_voltage_P1 = 0.00, max_voltage_P2 = 0.00;
456 uint8_t zelle_P1 = 0, zelle_P2 = 4;
457 float toleranz = 0.10;
459 akku_voltage_P1 = voltage[aktuelle_zelle_P1];
460 akku_voltage_P2 = voltage[aktuelle_zelle_P2];
464 for (
int i = 0; i <= 3; i++ )
468 aktuelle_zelle_P1 = i;
469 akku_voltage_P1 = voltage[i];
473 for (
int i = 4; i <= 7; i++ )
477 aktuelle_zelle_P2 = i;
478 akku_voltage_P2 = voltage[i];
487 h[aktuelle_zelle_P1][0] = now.hours;
488 m[aktuelle_zelle_P1][0] = now.minutes;
489 s[aktuelle_zelle_P1][0] = now.seconds;
491 h[aktuelle_zelle_P2][0] = now.hours;
492 m[aktuelle_zelle_P2][0] = now.minutes;
493 s[aktuelle_zelle_P2][0] = now.seconds;
495 entlade_start =
false;
500 for (
int i = 0; i <= 3; i++ )
504 if ( !akku_laden[i] )
506 if ( !flag_tupper[i] )
508 if ( voltage[i] > max_voltage_P1 )
510 max_voltage_P1 = voltage[i];
518 for (
int i = 4; i <= 7; i++ )
522 if ( !akku_laden[i] )
524 if ( !flag_tupper[i] )
526 if ( voltage[i] > max_voltage_P2 )
528 max_voltage_P2 = voltage[i];
542 if ( zelle_P1 != aktuelle_zelle_P1 )
544 if ( max_voltage_P1 > (akku_voltage_P1 + toleranz) )
548 aktuelle_zelle_P1 = zelle_P1;
550 h[aktuelle_zelle_P1][0] = now.hours;
551 m[aktuelle_zelle_P1][0] = now.minutes;
552 s[aktuelle_zelle_P1][0] = now.seconds;
555 if ( zelle_P2 != aktuelle_zelle_P2 )
557 if ( max_voltage_P2 > (akku_voltage_P2 + toleranz) )
561 aktuelle_zelle_P2 = zelle_P2;
563 h[aktuelle_zelle_P2][0] = now.hours;
564 m[aktuelle_zelle_P2][0] = now.minutes;
565 s[aktuelle_zelle_P2][0] = now.seconds;
568 PORTB.OUTSET = PIN1_bm;
595 for (
int i = 0; i <= 7; i++ )
597 charge[i] = charge[i] + current[i] * (WARTEZEIT / 3600.0);
600 if ( current[i] <= 10 ) c_max[i] = charge[i];
602 SOC[i] = charge[i] * 100 / c_max[i];
606 void lade_bestimmung (
void )
608 uint8_t B1 = 0, B2 = 0;
610 for (
int i = 0; i <= 3; i++ )
612 akku_laden[i] =
false;
616 if ( voltage[i] <= VOLTAGE_CRIT )
618 akku_laden[i] =
true;
621 else if ( SOC[i] <= SOC_CRIT )
623 akku_laden[i] =
true;
626 else if ( voltage[i] <= VOLTAGE_LOW )
628 akku_laden[i] =
true;
631 else if ( SOC[i] <= SOC_LOW )
633 akku_laden[i] =
true;
639 if ( B1 == 4 ) notstrom ();
641 for (
int i = 4; i <= 7; i++ )
643 akku_laden[i] =
false;
647 if ( voltage[i] <= VOLTAGE_CRIT )
649 akku_laden[i] =
true;
652 else if ( SOC[i] <= SOC_CRIT )
654 akku_laden[i] =
true;
657 else if ( voltage[i] <= VOLTAGE_LOW )
659 akku_laden[i] =
true;
662 else if ( SOC[i] <= SOC_LOW )
664 akku_laden[i] =
true;
670 if ( B2 == 4 ) notstrom ();
673 void notstrom (
void )
679 usb_versorgung =
false;
681 if ( PORTD_IN & LADE_POWER_IN_INT_bm )
685 mosfet_notstrom ( NOTSTROM_AUS );
687 else if ( PORTD_IN & USB_POWER_IN_INT_bm )
689 usb_versorgung =
true;
691 mosfet_notstrom ( NOTSTROM_AUS );
693 else if ( akku[4] && (voltage[4] >= VOLTAGE_CRIT) && !flag_tcrit[4] )
695 mosfet_notstrom ( NOTSTROM_AN );
701 if ( !(betriebsart == LEERLAUF) )
704 msgbox_notaus =
true;
708 void SOH_berechnung (
void )
710 for (
int i = 0; i <= 7; i++ )
712 if ( current[i] <= 10 )
714 SOH[i] = c_max[i] * 100 / CHARGE_MAX_CAPACITY;
719 void terminal_ausgabe ()
721 if ( !(betriebsart == LEERLAUF) )
724 leerlauf_voltage_get_data ();
728 printf (
"\x1B[2J\x1B[2;1H" );
729 printf (
"\x1B[1;33mB A T M A N\x1B[0m\r\n\r\n\r\n" );
731 if ( betriebsart == BETRIEB )
732 printf (
"\x1B[2;33mBETRIEB\x1B[0m\r\n\r\n" );
733 else if ( betriebsart == LADEN )
734 printf (
"\x1B[2;33mLADEN\x1B[0m\r\n\r\n" );
736 printf (
"\x1B[2;33mLEERLAUF\x1B[0m\r\n\r\n" );
738 printf (
"\x1B[2;31mBlock 1\x1B[0m\r\n" );
739 for (
int i = 0; i <= 3; i++ )
741 printf (
"\x1B[2;37mNummer \x1B[0m \x1B[1;37m%i\x1B[0m ", i );
742 printf (
"\x1B[2;37mCurrent\x1B[0m \x1B[1;37m%5imA\x1B[0m ", current[i] );
743 printf (
"\x1B[2;37mVoltage\x1B[0m \x1B[1;37m%5.2fV\x1B[0m ", voltage[i] );
744 printf (
"\x1B[2;37mTemperatur\x1B[0m \x1B[1;37m%i°C\x1B[0m ", temp[i] );
748 printf (
"\r\n\r\n" );
750 printf (
"\x1B[2;31mBlock 2\x1B[0m\r\n" );
751 for (
int i = 4; i <= 7; i++ )
753 printf (
"\x1B[2;37mNummer \x1B[0m \x1B[1;37m%i\x1B[0m ", i );
754 printf (
"\x1B[2;37mCurrent\x1B[0m \x1B[1;37m%5imA\x1B[0m ", current[i] );
755 printf (
"\x1B[2;37mVoltage\x1B[0m \x1B[1;37m%5.2fV\x1B[0m ", voltage[i] );
756 printf (
"\x1B[2;37mTemperatur\x1B[0m \x1B[1;37m%i°C\x1B[0m ", temp[i] );
761 void terminal_usb_ausgabe ()
763 if ( !(betriebsart == LEERLAUF) )
766 leerlauf_voltage_get_data ();
770 fprintf ( &
usbout,
"\x1B[2J\x1B[2;1H" );
771 fprintf ( &
usbout,
"\x1B[1;33mB A T M A N\x1B[0m\r\n\r\n\r\n" );
773 if ( betriebsart == BETRIEB )
774 fprintf ( &
usbout,
"\x1B[2;33mBETRIEB\x1B[0m\r\n\r\n" );
775 else if ( betriebsart == LADEN )
776 fprintf ( &
usbout,
"\x1B[2;33mLADEN\x1B[0m\r\n\r\n" );
778 fprintf ( &
usbout,
"\x1B[2;33mLEERLAUF\x1B[0m\r\n\r\n" );
780 fprintf ( &
usbout,
"\x1B[2;31mBlock 1\x1B[0m\r\n" );
781 for (
int i = 0; i <= 3; i++ )
783 fprintf ( &
usbout,
"\x1B[2;37mNummer \x1B[0m \x1B[1;37m%i\x1B[0m ", i );
784 fprintf ( &
usbout,
"\x1B[2;37mCurrent\x1B[0m \x1B[1;37m%5imA\x1B[0m ", current[i] );
785 fprintf ( &
usbout,
"\x1B[2;37mVoltage\x1B[0m \x1B[1;37m%5.2fV\x1B[0m ", voltage[i] );
786 fprintf ( &
usbout,
"\x1B[2;37mTemperatur\x1B[0m \x1B[1;37m%i°C\x1B[0m ", temp[i] );
787 fprintf ( &
usbout,
"\r\n" );
790 fprintf ( &
usbout,
"\r\n\r\n" );
792 fprintf ( &
usbout,
"\x1B[2;31mBlock 2\x1B[0m\r\n" );
793 for (
int i = 4; i <= 7; i++ )
795 fprintf ( &
usbout,
"\x1B[2;37mNummer \x1B[0m \x1B[1;37m%i\x1B[0m ", i );
796 fprintf ( &
usbout,
"\x1B[2;37mCurrent\x1B[0m \x1B[1;37m%5imA\x1B[0m ", current[i] );
797 fprintf ( &
usbout,
"\x1B[2;37mVoltage\x1B[0m \x1B[1;37m%5.2fV\x1B[0m ", voltage[i] );
798 fprintf ( &
usbout,
"\x1B[2;37mTemperatur\x1B[0m \x1B[1;37m%i°C\x1B[0m ", temp[i] );
799 fprintf ( &
usbout,
"\r\n" );
803 void excel_ausgabe ()
805 static bool einmal =
false;
809 printf (
"Zeit;Zelle;Vorhanden;Benutzung;Current;Voltage;Temperatur;Charge;SOC;SOH\n\r" );
814 for (
int battery_nmr = 0; battery_nmr <= 7; battery_nmr++ )
816 printf (
"%02i:%02i:%02i;%i;%i;%i;", now.hours, now.minutes, now.seconds, battery_nmr, akku[battery_nmr], akku_an[battery_nmr] );
817 printf (
"%i;%2.2f;%i;%2.2f;", current[battery_nmr], voltage[battery_nmr], temp[battery_nmr], charge[battery_nmr] );
818 printf (
"%i;%i\n\r", SOC[battery_nmr], SOH[battery_nmr] );
823 void zeit_berechnung (
void )
827 for (
int i = 0; i <= 7; i++ )
830 m[i][1] = now.minutes;
831 s[i][1] = now.seconds;
834 if ( betriebsart == LADEN )
836 for (
int i = 0; i <= 7; i++ )
838 ladezeit_s[i] += ((h[i][1] - h[i][0]) * 3600) + ((m[i][1] - m[i][0]) * 60) + (s[i][1] - s[i][0]);
840 m[i][0] = now.minutes;
841 s[i][0] = now.seconds;
844 else if ( betriebsart == BETRIEB )
846 for (
int i = 0; i <= 7; i++ )
850 betriebszeit_s[i] += ((h[i][1] - h[i][0]) * 3600) + ((m[i][1] - m[i][0]) * 60) + (s[i][1] - s[i][0]);
852 m[i][0] = now.minutes;
853 s[i][0] = now.seconds;
860 ISR( PORTD_INT1_vect )
877 if ( PORTD.IN & LADE_POWER_IN_INT_bm )
885 betriebsart = LEERLAUF;
896 ISR( PORTE_INT0_vect )
898 if ( PORTE_IN & LAST_bm )
Konstanten, Filter und Commands für den Temperatursensor MCP 9843.
Header, Definition der Konstanten und Commands für DS1388.
void mcp9843_get_data(void)
Die Daten des Temperatursensors werden ausgelesen.
void DS1388_get_datetime(void)
Die Uhrzeit und das Datum werden ausgelesen.
Standard board header file. Diese Datei enthält die Standardparameter und Pinbelegungen für das BMS B...
void ventilator(uint8_t ventNumber, bool set)
Schaltet einen Ventilator ein oder aus.
void sdcard_bms_read_state(void)
Zustandsdaten der Batterien werden gelesen.
FILE usbout
Filestreams für USB Kommunikation.
void bildschirm_ausgabe()
Belegung der Icon-Parameter für die Displayausgabe und Aufruf der verschiedenen Screens.
Standard Header Datei, Definition der Batteriekonstanten und Grenzwerte.
void message_notaus(void)
Messagebox mit Text NOTAUS.
void sdcard_bms_write_state(void)
Zustandsdaten der Batterien werden gespeichert.
Standardheader und Auswahl der Übertragungsgeschwindigkeit.
XMEGA TWI master driver header file.
void sdcard_bms_daten_laden(void)
Daten im Modus "Laden" werden auf die SD-Karte geschrieben.
void AD7997_voltage_get_data(void)
Ermittelt die Spannungen der Batterien.
void screen_home(void)
Der Home-Screen.
Standardheader. Definition der Iconfarben.
void SOC_berechnung(void)
Definition der Schalterstellungen für die einzelnen MOSFETs.
Standardheader. Datenmanagement für BMS-Daten mit SD Card Reader.
uint8_t zeit_counter
Main.
void mosfet_safeschaltung(void)
Sicherheitsschaltung der BMS-Platine, alle Funktionen sind aus.
void sdcard_bms_daten_betrieb(void)
Daten im Modus "Betrieb" werden auf die SD-Karte geschrieben.
void AD7997_current_get_data(void)
Ermittelt die Stromstärke in den Batteriestromkreisen.
#define COM74HC595_SIZE
Anzahl der über diesen Port anzusteuernden 74HC595 Bausteine.
void mosfet_charge_off(void)
Die Ladefunktion wird ausgeschaltet.
void mosfet_battery(uint8_t batteryNumber, bool set)
Einzelne Akkus werden in den Stromkreis zu- oder abgeschaltet.
Standardheader und Positionen der Zeilen und Spalten auf den jeweiligen Screens.
Header für ADC AD7997, Definition der Register und Commands.