Quinta87

Untitled

Oct 15th, 2021
20
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. cw beacon with telemetry and battery charging and discharge protection logic
  3. install library LowPower_LowPowerLab
  4. morse transmission code written by Nicola Salsotto IN3GJH
  5. https://github.com/NicoVarg99
  6. low power hibernation, voltages, temperature and emi measuring, charging battery logic written by quinta
  7. */
  8.  
  9.  
  10. #include "LowPower.h"
  11. #define SPEED (10) //morse speed WPM
  12. #define DOTLEN (1200/SPEED)
  13. #define DASHLEN (3*(1200/SPEED))
  14. #define PAUSE (180000) //pause between transmissions in milliseconds (not used in this project
  15. #define CARRIER (10000) // unmodulated carrier length symbol $
  16.  
  17. int txPin=10; //control PTT (turn on transmitter not used in simple transmitters)
  18. int txoffPin=11; //control PTT (turn off transmitter not used in simple transmitters)
  19. int ledPin=9; //cw dc out
  20. int tonePin=5; //cw tone out
  21. int chargePin=12; //battery charging control pin
  22. int emiPin=7; // emi amplifier power source
  23. int toneFreq=1209; //cw tone freq (choose 800 - 1500Hz)
  24. int adcbat = 0;
  25. int adcsol = 0;
  26. int adcemi = 0;
  27. void sendMsg(char*);
  28. void dash();
  29. void dot();
  30. const int in = A0; // temperature sensor diode pin
  31. const int t0 = 20.3; // temperature calibration point, measure the temperature and write in this constant
  32. const float vf0 = 522.02; // and measure voltage on diode and write in this constant
  33. // variables
  34. int i;
  35. float dtemp, dtemp_avg, tmp, sol, bat, emi;
  36.  
  37.  
  38. void setup()
  39. {
  40. pinMode(ledPin, OUTPUT);
  41. pinMode(txPin, OUTPUT);
  42. pinMode(txoffPin, OUTPUT);
  43. pinMode(A0, INPUT_PULLUP); // tenperature sensor pin IN with pull up to bias the diode
  44. pinMode(A1, INPUT);
  45. pinMode(A2, INPUT);
  46. pinMode(A3, INPUT);
  47. pinMode(tonePin, OUTPUT);
  48. pinMode(emiPin, OUTPUT);
  49. pinMode(chargePin, OUTPUT);
  50. // Serial.begin(9600);
  51. }
  52.  
  53.  
  54. void loop() //here we go
  55. {
  56. digitalWrite(chargePin, LOW); // for proper measuring disconnect solar battery and acid
  57. delay(1000); //wait some time for stabilising voltages
  58. adcbat = analogRead(A2); //measure voltages in binary
  59. adcsol = analogRead(A1);
  60. //calculating voltages
  61. bat = (adcbat / 1024.0)*3.3/*adc reference voltage*/*3.06 /*voltage divider coefficient(R(bat-adc)+R(adc-ground))/R(adc-ground)*/;
  62. sol = (adcsol / 1024.0)*3.3*3.06; //ну ты понел
  63.  
  64.  
  65. //if solar battery generate power, or acid battery have higher voltage than minimal
  66. //doing some data transformations from floating point to char array, and measuring and transform other telemetry
  67. //because cw transmission function cannot into float
  68. if ((bat > 5.8) || (sol > 5.9))
  69.  
  70. {
  71. char battery [7]; //yes, array length more than 5 symbols that you need, but you need 2 more chars for end of string symbol
  72. dtostrf(bat, 3, 1, battery);
  73. char solar [7];
  74. dtostrf(sol, 3, 1, solar);
  75. dtemp_avg = 0;
  76. for (i = 0; i < 100; i++)
  77. {
  78. float vf = analogRead(A0) * (3320.30 / 1023.000);
  79. dtemp = (vf - vf0) * 0.4545454;
  80. dtemp_avg = dtemp_avg + dtemp;
  81. }
  82. tmp = t0 - dtemp_avg / 100;
  83. char otemp[7];
  84. dtostrf(tmp, 5, 1, otemp);
  85.  
  86. digitalWrite(emiPin, HIGH); //turns on emi sensor rf amplifier
  87. delay(400);
  88. adcemi = analogRead(A3);// measuring detector voltage
  89. digitalWrite(emiPin, LOW); //turns off emi sensor
  90. emi = (adcemi / 1024.0)*3.3; //emi adc binary to volts transformation
  91. char emisense[7];
  92. dtostrf(emi, 5, 3, emisense);
  93. //Serial.println("TEST TEST TEST");
  94. //Serial.println(otemp);
  95. //Serial.println(tmp);
  96. //Serial.println(solar);
  97. //Serial.println(sol);
  98. //Serial.println(emisense);
  99. //Serial.println(emi);
  100. //Serial.println(battery);
  101. //Serial.println(bat);
  102.  
  103.  
  104.  
  105. //we collect all telemetry, time to send
  106. sendMsg("VVV CHI CHI "); //beacon call or any text you want to send
  107. sendMsg("TMP");
  108. sendMsg(otemp); //temperature
  109. sendMsg("SOL");
  110. sendMsg(solar);//solar battery voltage
  111. sendMsg("BAT");
  112. sendMsg(battery);//acid voltage
  113. sendMsg("EMI");
  114. sendMsg(emisense);//emi voltage
  115.  
  116.  
  117. delay (100); //after loading acid battery by transmitter we waiting to establish voltage on acid battery
  118. //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
  119. //if V solar > V acid+0/5v and if Vacid < 6.7 (acid not overcharged) we turn on charging
  120. adcbat = analogRead(A2);
  121. adcsol = analogRead(A1);
  122. bat = (adcbat / 1024.0)*3.3*3.06;
  123. sol = (adcsol / 1024.0)*3.3*3.06;
  124. if ((bat < 6.7) && (sol > (bat+0.5))) digitalWrite(chargePin, HIGH);
  125. else digitalWrite(chargePin, LOW);
  126. }
  127.  
  128.  
  129. //pause between telemetry transmission
  130. for (int i = 0; i < 75; i++) //i is number of 8 second deep hibernation periods
  131. //because 8 sec is maximum length of hibernation in low power library
  132. {
  133. LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF); //sleeeeep
  134. digitalWrite(chargePin, LOW); //disconnect power sources for proper voltages measuring
  135. adcbat = analogRead(A2); //and measuring
  136. adcsol = analogRead(A1);
  137. bat = (adcbat / 1024.0)*3.3*3.06;
  138. sol = (adcsol / 1024.0)*3.3*3.06;
  139. if ((bat > 5.8) || (sol > 5.9)) //if we have at least one power source we transmit dit
  140. {
  141. dot(); //transmit dit
  142. }
  143. if ((bat < 6.7) && (sol > (bat+0.5))) digitalWrite(chargePin, HIGH); //again deciding to charge acid or not
  144. else digitalWrite(chargePin, LOW);
  145.  
  146. }
  147. }
  148.  
  149.  
  150. void dash()
  151. {
  152. digitalWrite(ledPin, HIGH);
  153. tone(tonePin, toneFreq);
  154. delay(DASHLEN);
  155. digitalWrite(ledPin, LOW);
  156. noTone(tonePin);
  157. delay(DOTLEN);
  158. }
  159.  
  160.  
  161. void dot()
  162. {
  163. digitalWrite(ledPin, HIGH) ;
  164. tone(tonePin, toneFreq);
  165. delay(DOTLEN);
  166. digitalWrite(ledPin, LOW);
  167. noTone(tonePin);
  168. delay(DOTLEN);
  169. }
  170.  
  171.  
  172. void sendMsg(char *str)
  173. {
  174. int i;
  175.  
  176. delay(500);
  177.  
  178. for(i=0;i<strlen(str);i++)
  179. {
  180. switch (str[i])
  181. {
  182. case 'A':
  183. dot();dash();break;
  184. case 'B':
  185. dash();dot();dot();dot();break;
  186. case 'C':
  187. dash();dot();dash();dot();break;
  188. case 'D':
  189. dash();dot();dot();break;
  190. case 'E':
  191. dot();break;
  192. case 'F':
  193. dot();dot();dash();dot();break;
  194. case 'G':
  195. dash();dash();dot();break;
  196. case 'H':
  197. dot();dot();dot();dot();break;
  198. case 'I':
  199. dot();dot();break;
  200. case 'J':
  201. dot();dash();dash();dash();break;
  202. case 'K':
  203. dash();dot();dash();break;
  204. case 'L':
  205. dot();dash();dot();dot();break;
  206. case 'M':
  207. dash();dash();break;
  208. case 'N':
  209. dash();dot();break;
  210. case 'O':
  211. dash();dash();dash();break;
  212. case 'P':
  213. dot();dash();dash();dot();break;
  214. case 'Q':
  215. dash();dash();dot();dash();break;
  216. case 'R':
  217. dot();dash();dot();break;
  218. case 'S':
  219. dot();dot();dot();break;
  220. case 'T':
  221. dash();break;
  222. case 'U':
  223. dot();dot();dash();break;
  224. case 'V':
  225. dot();dot();dot();dash();break;
  226. case 'W':
  227. dot();dash();dash();break;
  228. case 'X':
  229. dash();dot();dot();dash();break;
  230. case 'Y':
  231. dash();dot();dash();dash();break;
  232. case 'Z':
  233. dash();dash();dot();dot();break;
  234. case ' ':
  235. delay(DOTLEN*5);break;
  236. case '.':
  237. dot();dash();dot();dash();dot();dash();break;
  238. case ',':
  239. dash();dash();dot();dot();dash();dash();break;
  240. case ':':
  241. dash();dash();dash();dot();dot();break;
  242. case '?':
  243. dot();dot();dash();dash();dot();dot();break;
  244. case '\'':
  245. dot();dash();dash();dash();dash();dot();break;
  246. case '-':
  247. dash();dot();dot();dot();dot();dash();break;
  248. case '/':
  249. dash();dot();dot();dash();dot();break;
  250. case '(':
  251. case ')':
  252. dash();dot();dash();dash();dot();dash();break;
  253. case '\"':
  254. dot();dash();dot();dot();dash();dot();break;
  255. case '@':
  256. dot();dash();dash();dot();dash();dot();break;
  257. case '$':
  258. delay(CARRIER);break;
  259. case '=':
  260. dash();dot();dot();dot();dash();break;
  261. case '0':
  262. dash();dash();dash();dash();dash();break;
  263. case '1':
  264. dot();dash();dash();dash();dash();break;
  265. case '2':
  266. dot();dot();dash();dash();dash();break;
  267. case '3':
  268. dot();dot();dot();dash();dash();break;
  269. case '4':
  270. dot();dot();dot();dot();dash();break;
  271. case '5':
  272. dot();dot();dot();dot();dot();break;
  273. case '6':
  274. dash();dot();dot();dot();dot();break;
  275. case '7':
  276. dash();dash();dot();dot();dot();break;
  277. case '8':
  278. dash();dash();dash();dot();dot();break;
  279. case '9':
  280. dash();dash();dash();dash();dot();break;
  281.  
  282. }
  283. delay(2*DOTLEN);
  284. }
  285.  
  286. }
RAW Paste Data