/* cw beacon with telemetry and battery charging and discharge protection logic install library LowPower_LowPowerLab morse transmission code written by Nicola Salsotto IN3GJH https://github.com/NicoVarg99 low power hibernation, voltages, temperature and emi measuring, charging battery logic written by quinta */ #include "LowPower.h" #define SPEED (10) //morse speed WPM #define DOTLEN (1200/SPEED) #define DASHLEN (3*(1200/SPEED)) #define PAUSE (180000) //pause between transmissions in milliseconds (not used in this project #define CARRIER (10000) // unmodulated carrier length symbol $ int txPin=10; //control PTT (turn on transmitter not used in simple transmitters) int txoffPin=11; //control PTT (turn off transmitter not used in simple transmitters) int ledPin=9; //cw dc out int tonePin=5; //cw tone out int chargePin=12; //battery charging control pin int emiPin=7; // emi amplifier power source int toneFreq=1209; //cw tone freq (choose 800 - 1500Hz) int adcbat = 0; int adcsol = 0; int adcemi = 0; void sendMsg(char*); void dash(); void dot(); const int in = A0; // temperature sensor diode pin const int t0 = 20.3; // temperature calibration point, measure the temperature and write in this constant const float vf0 = 522.02; // and measure voltage on diode and write in this constant // variables int i; float dtemp, dtemp_avg, tmp, sol, bat, emi; void setup() { pinMode(ledPin, OUTPUT); pinMode(txPin, OUTPUT); pinMode(txoffPin, OUTPUT); pinMode(A0, INPUT_PULLUP); // tenperature sensor pin IN with pull up to bias the diode pinMode(A1, INPUT); pinMode(A2, INPUT); pinMode(A3, INPUT); pinMode(tonePin, OUTPUT); pinMode(emiPin, OUTPUT); pinMode(chargePin, OUTPUT); // Serial.begin(9600); } void loop() //here we go { digitalWrite(chargePin, LOW); // for proper measuring disconnect solar battery and acid delay(1000); //wait some time for stabilising voltages adcbat = analogRead(A2); //measure voltages in binary adcsol = analogRead(A1); //calculating voltages bat = (adcbat / 1024.0)*3.3/*adc reference voltage*/*3.06 /*voltage divider coefficient(R(bat-adc)+R(adc-ground))/R(adc-ground)*/; sol = (adcsol / 1024.0)*3.3*3.06; //ну ты понел //if solar battery generate power, or acid battery have higher voltage than minimal //doing some data transformations from floating point to char array, and measuring and transform other telemetry //because cw transmission function cannot into float if ((bat > 5.8) || (sol > 5.9)) { char battery [7]; //yes, array length more than 5 symbols that you need, but you need 2 more chars for end of string symbol dtostrf(bat, 3, 1, battery); char solar [7]; dtostrf(sol, 3, 1, solar); dtemp_avg = 0; for (i = 0; i < 100; i++) { float vf = analogRead(A0) * (3320.30 / 1023.000); dtemp = (vf - vf0) * 0.4545454; dtemp_avg = dtemp_avg + dtemp; } tmp = t0 - dtemp_avg / 100; char otemp[7]; dtostrf(tmp, 5, 1, otemp); digitalWrite(emiPin, HIGH); //turns on emi sensor rf amplifier delay(400); adcemi = analogRead(A3);// measuring detector voltage digitalWrite(emiPin, LOW); //turns off emi sensor emi = (adcemi / 1024.0)*3.3; //emi adc binary to volts transformation char emisense[7]; dtostrf(emi, 5, 3, emisense); //Serial.println("TEST TEST TEST"); //Serial.println(otemp); //Serial.println(tmp); //Serial.println(solar); //Serial.println(sol); //Serial.println(emisense); //Serial.println(emi); //Serial.println(battery); //Serial.println(bat); //we collect all telemetry, time to send sendMsg("VVV CHI CHI "); //beacon call or any text you want to send sendMsg("TMP"); sendMsg(otemp); //temperature sendMsg("SOL"); sendMsg(solar);//solar battery voltage sendMsg("BAT"); sendMsg(battery);//acid voltage sendMsg("EMI"); sendMsg(emisense);//emi voltage delay (100); //after loading acid battery by transmitter we waiting to establish voltage on acid battery //because transmission length about 1 minute solar battery lighting may change we measuring power voltages again to decide: turn on charge acid battery or not //if V solar > V acid+0/5v and if Vacid < 6.7 (acid not overcharged) we turn on charging adcbat = analogRead(A2); adcsol = analogRead(A1); bat = (adcbat / 1024.0)*3.3*3.06; sol = (adcsol / 1024.0)*3.3*3.06; if ((bat < 6.7) && (sol > (bat+0.5))) digitalWrite(chargePin, HIGH); else digitalWrite(chargePin, LOW); } //pause between telemetry transmission for (int i = 0; i < 75; i++) //i is number of 8 second deep hibernation periods //because 8 sec is maximum length of hibernation in low power library { LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF); //sleeeeep digitalWrite(chargePin, LOW); //disconnect power sources for proper voltages measuring adcbat = analogRead(A2); //and measuring adcsol = analogRead(A1); bat = (adcbat / 1024.0)*3.3*3.06; sol = (adcsol / 1024.0)*3.3*3.06; if ((bat > 5.8) || (sol > 5.9)) //if we have at least one power source we transmit dit { dot(); //transmit dit } if ((bat < 6.7) && (sol > (bat+0.5))) digitalWrite(chargePin, HIGH); //again deciding to charge acid or not else digitalWrite(chargePin, LOW); } } void dash() { digitalWrite(ledPin, HIGH); tone(tonePin, toneFreq); delay(DASHLEN); digitalWrite(ledPin, LOW); noTone(tonePin); delay(DOTLEN); } void dot() { digitalWrite(ledPin, HIGH) ; tone(tonePin, toneFreq); delay(DOTLEN); digitalWrite(ledPin, LOW); noTone(tonePin); delay(DOTLEN); } void sendMsg(char *str) { int i; delay(500); for(i=0;i