radioEmission.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. #include <wiringPi.h>
  2. #include <iostream>
  3. #include <stdio.h>
  4. #include <sys/time.h>
  5. #include <time.h>
  6. #include <stdlib.h>
  7. #include <sched.h>
  8. #include <sstream>
  9. /*
  10. Par Idleman (idleman@idleman.fr - http://blog.idleman.fr)
  11. Licence : CC by sa
  12. Toutes question sur le blog ou par mail, possibilité de m'envoyer des bières via le blog
  13. */
  14. //g++ radioEmission.cpp -o radioEmission -lwiringPi pour recompiler
  15. using namespace std;
  16. int pin;
  17. bool bit2[26]={}; // 26 bit Identifiant emetteur
  18. bool bit2Interruptor[4]={};
  19. int interruptor;
  20. int sender;
  21. string onoff;
  22. int pulse=0;
  23. void log(string a){
  24. //Décommenter pour avoir les logs
  25. //cout << a << endl;
  26. }
  27. void scheduler_realtime() {
  28. struct sched_param p;
  29. p.__sched_priority = sched_get_priority_max(SCHED_RR);
  30. if( sched_setscheduler( 0, SCHED_RR, &p ) == -1 ) {
  31. perror("Failed to switch to realtime scheduler.");
  32. }
  33. }
  34. void scheduler_standard() {
  35. struct sched_param p;
  36. p.__sched_priority = 0;
  37. if( sched_setscheduler( 0, SCHED_OTHER, &p ) == -1 ) {
  38. perror("Failed to switch to normal scheduler.");
  39. }
  40. }
  41. //Envois d'une pulsation (passage de l'etat haut a l'etat bas)
  42. //1 = 310µs haut puis 1340µs bas
  43. //0 = 310µs haut puis 310µs bas
  44. void sendBit(bool b) {
  45. if (b) {
  46. digitalWrite(pin, HIGH);
  47. delayMicroseconds(310); //275 orinally, but tweaked.
  48. digitalWrite(pin, LOW);
  49. delayMicroseconds(1340); //1225 orinally, but tweaked.
  50. }
  51. else {
  52. digitalWrite(pin, HIGH);
  53. delayMicroseconds(310); //275 orinally, but tweaked.
  54. digitalWrite(pin, LOW);
  55. delayMicroseconds(310); //275 orinally, but tweaked.
  56. }
  57. }
  58. //Calcul le nombre 2^chiffre indiqué, fonction utilisé par itob pour la conversion decimal/binaire
  59. unsigned long power2(int power){
  60. unsigned long integer=1;
  61. for (int i=0; i<power; i++){
  62. integer*=2;
  63. }
  64. return integer;
  65. }
  66. //Convertis un nombre en binaire, nécessite le nombre, et le nombre de bits souhaité en sortie (ici 26)
  67. // Stocke le résultat dans le tableau global "bit2"
  68. void itob(unsigned long integer, int length)
  69. {
  70. for (int i=0; i<length; i++){
  71. if ((integer / power2(length-1-i))==1){
  72. integer-=power2(length-1-i);
  73. bit2[i]=1;
  74. }
  75. else bit2[i]=0;
  76. }
  77. }
  78. void itobInterruptor(unsigned long integer, int length)
  79. {
  80. for (int i=0; i<length; i++){
  81. if ((integer / power2(length-1-i))==1){
  82. integer-=power2(length-1-i);
  83. bit2Interruptor[i]=1;
  84. }
  85. else bit2Interruptor[i]=0;
  86. }
  87. }
  88. //Envoie d'une paire de pulsation radio qui definissent 1 bit réel : 0 =01 et 1 =10
  89. //c'est le codage de manchester qui necessite ce petit bouzin, ceci permet entre autres de dissocier les données des parasites
  90. void sendPair(bool b) {
  91. if(b)
  92. {
  93. sendBit(true);
  94. sendBit(false);
  95. }
  96. else
  97. {
  98. sendBit(false);
  99. sendBit(true);
  100. }
  101. }
  102. //Fonction d'envois du signal
  103. //recoit en parametre un booleen définissant l'arret ou la marche du matos (true = on, false = off)
  104. void transmit(int blnOn)
  105. {
  106. int i;
  107. // Sequence de verrou anoncant le départ du signal au recepeteur
  108. digitalWrite(pin, HIGH);
  109. delayMicroseconds(275); // un bit de bruit avant de commencer pour remettre les delais du recepteur a 0
  110. digitalWrite(pin, LOW);
  111. delayMicroseconds(9900); // premier verrou de 9900µs
  112. digitalWrite(pin, HIGH); // high again
  113. delayMicroseconds(275); // attente de 275µs entre les deux verrous
  114. digitalWrite(pin, LOW); // second verrou de 2675µs
  115. delayMicroseconds(2675);
  116. digitalWrite(pin, HIGH); // On reviens en état haut pour bien couper les verrous des données
  117. // Envoie du code emetteur (272946 = 1000010101000110010 en binaire)
  118. for(i=0; i<26;i++)
  119. {
  120. sendPair(bit2[i]);
  121. }
  122. // Envoie du bit définissant si c'est une commande de groupe ou non (26em bit)
  123. sendPair(false);
  124. // Envoie du bit définissant si c'est allumé ou eteint 27em bit)
  125. sendPair(blnOn);
  126. // Envoie des 4 derniers bits, qui représentent le code interrupteur, ici 0 (encode sur 4 bit donc 0000)
  127. // nb: sur les télécommandes officielle chacon, les interrupteurs sont logiquement nommés de 0 à x
  128. // interrupteur 1 = 0 (donc 0000) , interrupteur 2 = 1 (1000) , interrupteur 3 = 2 (0100) etc...
  129. for(i=0; i<4;i++)
  130. {
  131. if(bit2Interruptor[i]==0){
  132. sendPair(false);
  133. }else{
  134. sendPair(true);
  135. }
  136. }
  137. digitalWrite(pin, HIGH); // coupure données, verrou
  138. delayMicroseconds(275); // attendre 275µs
  139. digitalWrite(pin, LOW); // verrou 2 de 2675µs pour signaler la fermeture du signal
  140. }
  141. void action (bool b) {
  142. if (b) {
  143. log("envois du signal ON");
  144. } else {
  145. log("envois du signal OFF");
  146. }
  147. for(int i=0;i<5;i++){
  148. transmit(b); // envoyer
  149. delay(10); // attendre 10 ms (sinon le socket nous ignore)
  150. }
  151. }
  152. int main (int argc, char** argv)
  153. {
  154. if (setuid(0))
  155. {
  156. perror("setuid");
  157. return 1;
  158. }
  159. scheduler_realtime();
  160. log("Demarrage du programme");
  161. pin = atoi(argv[1]);
  162. sender = atoi(argv[2]);
  163. interruptor = atoi(argv[3]);
  164. onoff = argv[4];
  165. if (argc==6) {
  166. pulse = atoi(argv[5]);
  167. }
  168. //Si on ne trouve pas la librairie wiringPI, on arrête l'execution
  169. if(wiringPiSetup() == -1)
  170. {
  171. log("Librairie Wiring PI introuvable, veuillez lier cette librairie...");
  172. return -1;
  173. }
  174. pinMode(pin, OUTPUT);
  175. log("Pin GPIO configure en sortie");
  176. itob(sender,26); // convertion du code de l'emetteur (ici 8217034) en code binaire
  177. itobInterruptor(interruptor,4);
  178. if(onoff=="on"){
  179. action(true);
  180. }else if (onoff=="off"){
  181. action(false);
  182. }else{
  183. action(true);
  184. delay(pulse);
  185. action(false);
  186. }
  187. log("fin du programme"); // execution terminée.
  188. scheduler_standard();
  189. }