Различия
Здесь показаны различия между двумя версиями данной страницы.
Следующая версия | Предыдущая версия | ||
doc:jroboplc:ups_devices:ups_nano_src [2018/06/25 13:23] denis создано |
doc:jroboplc:ups_devices:ups_nano_src [2018/07/27 13:21] (текущий) denis |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
- | <file aaa> | + | <file cpp sketch_ups_nano_1.ino> |
+ | #include <EEPROM.h> | ||
+ | #include <CRC32.h> | ||
+ | #include <OneWire.h> | ||
+ | #include <DallasTemperature.h> | ||
+ | |||
+ | #define pinInpT 2 | ||
+ | #define pinInpACOK 3 | ||
+ | #define pinInpBatLow 4 | ||
+ | #define pinInpAux 5 | ||
+ | #define pinOutLedBat 6 | ||
+ | #define pinOutLedPlc 7 | ||
+ | #define pinOutBeep 8 | ||
+ | #define pinOutBatCtrl 9 | ||
+ | #define pinOutCooler 10 | ||
+ | #define pinOutAux 11 | ||
+ | #define pinOutLedRun LED_BUILTIN | ||
+ | |||
+ | #define VERSION 0 | ||
+ | #define REQUEST_LEN 15 | ||
+ | #define REQUEST_TIMEOUT 100 | ||
+ | #define DEFAULT_TIMEOUT_SERIAL 10 | ||
+ | #define DEFAULT_TIMEOUT_BATCTRL 5 | ||
+ | |||
+ | #define ADDR_SERIAL_CONNECTED 0 | ||
+ | #define ADDR_BAT_CTRL 2 | ||
+ | #define ADDR_T_OFF 4 | ||
+ | #define ADDR_T_ON 6 | ||
+ | #define ADDR_BEEP_MODE 8 | ||
+ | |||
+ | OneWire oneWire(pinInpT); | ||
+ | DallasTemperature dallasTemp(&oneWire); | ||
+ | |||
+ | |||
+ | int T; | ||
+ | int Toff; | ||
+ | int Ton; | ||
+ | |||
+ | boolean outBeep; | ||
+ | boolean outBatCtrl; | ||
+ | boolean outCooler; | ||
+ | boolean outAux; | ||
+ | boolean outLedBat; | ||
+ | boolean outLedPlc; | ||
+ | |||
+ | boolean manual_BatCtrl; | ||
+ | boolean manual_Cooler; | ||
+ | int beep_mode; | ||
+ | |||
+ | int timeBatCtrl; | ||
+ | int cntBatCtrl; | ||
+ | |||
+ | int cntLedPlc; | ||
+ | |||
+ | long ms; | ||
+ | int cnt5000ms; | ||
+ | int cnt1000ms; | ||
+ | int cnt200ms; | ||
+ | |||
+ | boolean serConnected; | ||
+ | int timeoutSerialConnected; | ||
+ | long serms; | ||
+ | int sercnt; | ||
+ | uint8_t serbuf[REQUEST_LEN]; | ||
+ | |||
+ | boolean auxIfNotConnected; | ||
+ | |||
+ | void setup() { | ||
+ | pinMode(pinInpACOK, INPUT); | ||
+ | pinMode(pinInpBatLow, INPUT); | ||
+ | pinMode(pinInpAux, INPUT); | ||
+ | pinMode(pinOutLedBat, OUTPUT); | ||
+ | pinMode(pinOutLedPlc, OUTPUT); | ||
+ | pinMode(pinOutBeep, OUTPUT); | ||
+ | pinMode(pinOutBatCtrl, OUTPUT); | ||
+ | pinMode(pinOutCooler, OUTPUT); | ||
+ | pinMode(pinOutAux, OUTPUT); | ||
+ | pinMode(pinOutLedRun, OUTPUT); | ||
+ | |||
+ | Serial.begin(9600); | ||
+ | |||
+ | dallasTemp.begin(); | ||
+ | dallasTemp.setWaitForConversion(false); | ||
+ | dallasTemp.requestTemperatures(); | ||
+ | |||
+ | manual_BatCtrl = false; | ||
+ | manual_Cooler = false; | ||
+ | cnt5000ms = 0; | ||
+ | cnt1000ms = 0; | ||
+ | cnt200ms = 0; | ||
+ | cntLedPlc = 0; | ||
+ | cntBatCtrl = 0; | ||
+ | auxIfNotConnected = false; | ||
+ | sercnt = 0; | ||
+ | serConnected = false; | ||
+ | ms = millis(); | ||
+ | |||
+ | EEPROM.get(ADDR_SERIAL_CONNECTED, timeoutSerialConnected); | ||
+ | EEPROM.get(ADDR_BAT_CTRL, timeBatCtrl); | ||
+ | EEPROM.get(ADDR_T_OFF, Toff); | ||
+ | EEPROM.get(ADDR_T_ON, Ton); | ||
+ | EEPROM.get(ADDR_BEEP_MODE, beep_mode); | ||
+ | |||
+ | validate_vars(); | ||
+ | greeting(); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void greeting() { | ||
+ | Serial.print("UPS NANO version "); | ||
+ | Serial.println(VERSION); | ||
+ | |||
+ | Serial.print("SerTimeout = "); | ||
+ | Serial.println(timeoutSerialConnected); | ||
+ | Serial.print("BatCtrlTimeout = "); | ||
+ | Serial.println(timeBatCtrl); | ||
+ | Serial.print("Toff = "); | ||
+ | Serial.println(Toff); | ||
+ | Serial.print("Ton = "); | ||
+ | Serial.println(Ton); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void validate_vars() { | ||
+ | if(timeBatCtrl <= 0) | ||
+ | timeBatCtrl = 1; | ||
+ | |||
+ | if(timeoutSerialConnected <= 0) | ||
+ | timeoutSerialConnected = 1; | ||
+ | |||
+ | if(beep_mode < 0 || beep_mode > 2) | ||
+ | beep_mode = 0; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void loop() { | ||
+ | long msdelta = millis() - ms; | ||
+ | if( msdelta >= 100 ) { | ||
+ | ms += 100; | ||
+ | loop100ms(); | ||
+ | } else | ||
+ | if( msdelta < 0 ) { | ||
+ | msdelta += 0x80000000L; | ||
+ | if( msdelta >= 100 ) { | ||
+ | ms += 100 + 0x80000000L; | ||
+ | loop100ms(); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if( Serial ) { | ||
+ | if( Serial.available() == 0 ) { | ||
+ | msdelta = millis() - serms; | ||
+ | if( msdelta < 0 ) | ||
+ | msdelta += 0x80000000L; | ||
+ | if( sercnt > 0 && msdelta > REQUEST_TIMEOUT ) { | ||
+ | sercnt = 0; | ||
+ | serConnected = false; | ||
+ | } | ||
+ | if( serConnected && (msdelta/1000) >= timeoutSerialConnected ) { | ||
+ | serConnected = false; | ||
+ | } | ||
+ | } else { | ||
+ | while( Serial.available() > 0 ) { | ||
+ | serbuf[sercnt++] = Serial.read(); | ||
+ | if( sercnt == REQUEST_LEN ) { | ||
+ | onSerRequest(); | ||
+ | sercnt = 0; | ||
+ | // serConnected = true; | ||
+ | } | ||
+ | } | ||
+ | serms = millis(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void loop100ms() { | ||
+ | if( cnt5000ms++ >= 50 ) { | ||
+ | cnt5000ms = 0; | ||
+ | loop5000ms(); | ||
+ | } | ||
+ | |||
+ | if( cnt1000ms++ >= 10 ) { | ||
+ | cnt1000ms = 0; | ||
+ | loop1000ms(); | ||
+ | } | ||
+ | |||
+ | if( cnt200ms++ >= 2 ) { | ||
+ | cnt200ms = 0; | ||
+ | loop200ms(); | ||
+ | } | ||
+ | |||
+ | // led plc | ||
+ | if( !serConnected ) { | ||
+ | if( cntLedPlc++ < 10 ) | ||
+ | outLedPlc = cntLedPlc % 2; | ||
+ | else if( cntLedPlc >= 30 ) { | ||
+ | outLedPlc = false; | ||
+ | cntLedPlc = 0; | ||
+ | } | ||
+ | } else | ||
+ | cntLedPlc = 0; | ||
+ | |||
+ | digitalWrite(pinOutLedPlc, !outLedPlc); //inv | ||
+ | digitalWrite(pinOutLedRun, !outLedPlc); //inv | ||
+ | digitalWrite(pinOutLedBat, !outLedBat); //inv | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void loop200ms() { | ||
+ | // led bat | ||
+ | if( digitalRead(pinInpACOK) ) { //inv | ||
+ | if( (!digitalRead(pinInpBatLow)) == HIGH ) //inv | ||
+ | outLedBat = !outLedBat; | ||
+ | else | ||
+ | outLedBat = HIGH; | ||
+ | } else | ||
+ | outLedBat = LOW; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void loop1000ms() { | ||
+ | if( serConnected ) | ||
+ | outLedPlc = !outLedPlc; | ||
+ | |||
+ | // bat control | ||
+ | if( !manual_BatCtrl ) { | ||
+ | outBatCtrl = 1; | ||
+ | if( timeBatCtrl > 0 && !serConnected ) { | ||
+ | if( digitalRead(pinInpACOK) ) { //inv | ||
+ | if( cntBatCtrl >= timeBatCtrl ) { | ||
+ | outBatCtrl = 0; | ||
+ | } else | ||
+ | cntBatCtrl++; | ||
+ | } else | ||
+ | cntBatCtrl = 0; | ||
+ | } | ||
+ | } | ||
+ | digitalWrite(pinOutBatCtrl, outBatCtrl); // | ||
+ | |||
+ | // beep | ||
+ | if( digitalRead(pinInpACOK) ) { //inv | ||
+ | if( outBeep = !outBeep ) | ||
+ | // second arg: | ||
+ | // 1200 - normal tone | ||
+ | // 40 - debug tone (very low) | ||
+ | if( beep_mode == 0 ) | ||
+ | tone(pinOutBeep, 1200, 1000); | ||
+ | else if( beep_mode == 1 ) | ||
+ | tone(pinOutBeep, 40, 1000); | ||
+ | else | ||
+ | noTone(pinOutBeep); | ||
+ | } | ||
+ | |||
+ | // aux | ||
+ | if(auxIfNotConnected) | ||
+ | outAux = !serConnected; | ||
+ | digitalWrite(pinOutAux, !outAux); //inv | ||
+ | |||
+ | // cooler | ||
+ | int t = (int)round(dallasTemp.getTempCByIndex(0) * 10); | ||
+ | dallasTemp.requestTemperatures(); | ||
+ | if( t > -500 && t < 1200 ) | ||
+ | T = t; | ||
+ | |||
+ | if( !manual_Cooler ) { | ||
+ | if( Ton > Toff? T >= Ton: T <= Ton ) | ||
+ | outCooler = 1; | ||
+ | else | ||
+ | if( Ton > Toff? T <= Toff: T >= Toff ) | ||
+ | outCooler = 0; | ||
+ | } | ||
+ | digitalWrite(pinOutCooler, !outCooler); //inv | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void loop5000ms() { | ||
+ | } | ||
+ | |||
+ | |||
+ | void onSerRequest() { | ||
+ | serConnected = false; | ||
+ | |||
+ | uint32_t cs1 = CRC32::calculate(serbuf, REQUEST_LEN-4); | ||
+ | uint32_t cs2 = | ||
+ | (((uint32_t)serbuf[REQUEST_LEN-4])<<24) + | ||
+ | (((uint32_t)serbuf[REQUEST_LEN-3])<<16) + | ||
+ | (((uint32_t)serbuf[REQUEST_LEN-2])<<8) + | ||
+ | (uint32_t)serbuf[REQUEST_LEN-1]; | ||
+ | |||
+ | if( cs1 != cs2 ) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | if( serbuf[0] != VERSION ) { | ||
+ | sendErrorVersion(); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | getSerbufValues(); | ||
+ | sendGoodAnswer(); | ||
+ | |||
+ | serConnected = true; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void sendGoodAnswer() { | ||
+ | serbuf[0] = 0; | ||
+ | serbuf[1] = (!digitalRead(pinInpACOK)) + (!digitalRead(pinInpBatLow))*2 + (!digitalRead(pinInpAux))*4; | ||
+ | serbuf[2] = (T >> 8) & 0xFF; | ||
+ | serbuf[3] = T & 0xFF; | ||
+ | |||
+ | addSerbufCrc(4); | ||
+ | Serial.write(serbuf, 8); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void sendErrorVersion() { | ||
+ | serbuf[0] = 0xFF; | ||
+ | serbuf[1] = VERSION; | ||
+ | serbuf[2] = serbuf[3] = 0; | ||
+ | addSerbufCrc(4); | ||
+ | Serial.write(serbuf, 8); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void addSerbufCrc(int len) { | ||
+ | uint32_t cs = CRC32::calculate(serbuf, len); | ||
+ | serbuf[len++] = cs >> 24; | ||
+ | serbuf[len++] = (cs %= 0x1000000) >> 16; | ||
+ | serbuf[len++] = (cs %= 0x10000) >> 8; | ||
+ | serbuf[len++] = cs %= 0x100; | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | void getSerbufValues() { | ||
+ | timeBatCtrl = | ||
+ | (serbuf[1] << 8) + | ||
+ | serbuf[2]; | ||
+ | |||
+ | timeoutSerialConnected = | ||
+ | (serbuf[3] << 8) + | ||
+ | serbuf[4]; | ||
+ | |||
+ | Ton = | ||
+ | (serbuf[5] << 8) + | ||
+ | serbuf[6]; | ||
+ | |||
+ | Toff = | ||
+ | (serbuf[7] << 8) + | ||
+ | serbuf[8]; | ||
+ | |||
+ | int aux_mode = | ||
+ | serbuf[9] & 3; | ||
+ | |||
+ | if( aux_mode == 0 ) | ||
+ | outAux = 0; | ||
+ | else if( aux_mode == 1 ) | ||
+ | outAux = 1; | ||
+ | auxIfNotConnected = (aux_mode == 2); | ||
+ | |||
+ | int manuals = | ||
+ | serbuf[10]; | ||
+ | |||
+ | manual_BatCtrl = (manuals & 0x1) > 0; | ||
+ | if( manual_BatCtrl ) | ||
+ | outBatCtrl = (manuals & 0x2) > 0; | ||
+ | |||
+ | manual_Cooler = (manuals & 0x4) > 0; | ||
+ | if( manual_Cooler ) | ||
+ | outCooler = (manuals & 0x8) > 0; | ||
+ | |||
+ | beep_mode = (manuals >> 4) & 0xF; | ||
+ | |||
+ | validate_vars(); | ||
+ | |||
+ | EEPROM.put(ADDR_SERIAL_CONNECTED, timeoutSerialConnected); | ||
+ | EEPROM.put(ADDR_BAT_CTRL, timeBatCtrl); | ||
+ | EEPROM.put(ADDR_T_OFF, Toff); | ||
+ | EEPROM.put(ADDR_T_ON, Ton); | ||
+ | EEPROM.put(ADDR_BEEP_MODE, beep_mode); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
</file> | </file> |