Guest User

Untitled

a guest
Jul 23rd, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.39 KB | None | 0 0
  1. //This is an attempt at creating an RC Transmitter and Reciver in a single firmware.. why.. I don't know.
  2. #include <EEPROM.h>
  3. #include <Wire.h>
  4. #include <string.h>
  5. #undef int
  6. #include <stdio.h>
  7.  
  8. uint8_t outbuf[6]; //array to store nunchuck output
  9. int cnt = 0; //nunchuck byte recieved counter
  10.  
  11. char serialenabled=false;
  12. long int previousMillis=millis();
  13. long int previousRefresh=millis();
  14. long int wholestatus=millis();
  15. #define USERINPUTS 5
  16. char userinputname[USERINPUTS];
  17. int userinputmin[USERINPUTS];
  18. int userinputmax[USERINPUTS];
  19. int userinputlval[USERINPUTS];
  20. int userinputval[USERINPUTS];
  21. int userinputreverse[USERINPUTS];
  22. int v=0;
  23. int editinput=0; // which input is currently in edit mode.
  24. //EEPROM address mapping: first 4 bytes are reverse settings.
  25. #define OFFSETFORREVERSE 0
  26. //after that is min settings.
  27. #define OFFSETFORMINS OFFSETFORREVERSE + USERINPUTS
  28. //after that is max settings.
  29. //#define OFFSETFORMAXS OFFSETFORREVERSE + (OFFSETFORMINS + USERINPUTS * 2)
  30. #define OFFSETFORMAXS 12
  31. //Those are each the starting positions in memory for where the array is stored.
  32. char ledState=0;
  33. #define LED_PIN 13
  34. #define XBEEPWR1_PIN 9
  35. #define XBEEPWR2_PIN 8
  36. #define NUNCHUCKPWR1_PIN 10
  37. #define NUNCHUCKPWR2_PIN 11
  38.  
  39. void sendvalue(int i)
  40. {
  41. userinputlval[i]=userinputval[i];
  42. if (userinputval[i] < userinputmin[i] || userinputval[i] > userinputmax[i])
  43. return;
  44. if (1024 < userinputmin[i] || 0 > userinputmax[i])
  45. return;
  46. if (userinputmin[i] > userinputmax[i])
  47. return;
  48. if (userinputreverse[i] == false )
  49. {
  50. userinputval[i]=map(userinputval[i],userinputmin[i],userinputmax[i],0,180); //180 because of servo's..
  51. }
  52. else
  53. {
  54. userinputval[i]=map(userinputval[i],userinputmin[i],userinputmax[i],180,0); //180 because of servo's..
  55. }
  56. constrain(userinputval[i],0,180);
  57. Serial.print(userinputval[i],DEC);
  58. Serial.print(userinputname[i]);
  59. // Serial.flush();
  60. digitalWrite(LED_PIN,ledState=!ledState);
  61. }
  62.  
  63. void handleserialinput(void)
  64. {
  65. if (Serial.available() && serialenabled == true)
  66. {
  67. int i;
  68. char ch = Serial.read();
  69. switch(ch) {
  70. case '0'...'9':
  71. v = v * 10 + ch - '0';
  72. break;
  73. case '$':
  74. serialenabled=false;
  75. Serial.println("\n# Serial disabled");
  76. break;
  77. case 'e'://set which input to edit.
  78. if ( v < 0 || v >= USERINPUTS)
  79. {
  80. Serial.println("\n#reverse: can't change.. invalid input specified. please use 0-USERINPUTS");
  81. v=0;
  82. break;
  83. }
  84. editinput=v;
  85. Serial.print("\n#now we'll edit input ");
  86. Serial.println(editinput,DEC);
  87. v=0;
  88. break;
  89. case 'E'://edit input name...
  90. if ( Serial.available())
  91. v=Serial.read();
  92. if ( v > '0' && v < '9')
  93. {
  94. Serial.println("\n#cannot set input name.. invalid char.");
  95. v=0;
  96. break;
  97. }
  98. userinputname[editinput]=v;
  99. Serial.print("\n#input ");
  100. Serial.print(editinput,DEC);
  101. Serial.print(" name is now ");
  102. Serial.println(v);
  103. v=0;
  104. break;
  105. case 'm'://set minimum value exptected from input.
  106. if ( v < 0 || v > 1024)
  107. {
  108. Serial.println("\n#minimum value out of range.. use 0-1024");
  109. v=0;
  110. break;
  111. }
  112. userinputmin[editinput]=v;
  113. EEPROM.write(editinput*2+OFFSETFORMINS,v >> 8);
  114. EEPROM.write(editinput*2+1+OFFSETFORMINS,v);
  115. v=EEPROM.read(editinput*2+OFFSETFORMINS);
  116. v=v << 8;
  117. v=EEPROM.read(editinput*2+1+OFFSETFORMINS) + v;
  118.  
  119. Serial.print("\n#Minimum value for input ");
  120. Serial.print(editinput,DEC);
  121. Serial.print(" set to ");
  122. Serial.print(userinputmin[editinput],DEC);
  123. Serial.print(" from ");
  124. Serial.println(v,DEC);
  125. v=0;
  126. break;
  127. case 'M'://set maximum value exptected from input.
  128. if ( v < 0 || v > 1024)
  129. {
  130. Serial.println("\n#maximum value out of range.. use 0-1024");
  131. v=0;
  132. break;
  133. }
  134. userinputmax[editinput]=v;
  135. EEPROM.write(editinput*2+OFFSETFORMAXS,v >> 8);
  136. EEPROM.write(editinput*2+1+OFFSETFORMAXS,v);
  137. v=EEPROM.read(editinput*2+OFFSETFORMAXS);
  138. v=v << 8;
  139. v=EEPROM.read(editinput*2+1+OFFSETFORMAXS) + v;
  140. Serial.print("\n#Maximum value for input ");
  141. Serial.print(editinput,DEC);
  142. Serial.print(" set to ");
  143. Serial.print(userinputmin[editinput],DEC);
  144. Serial.print(" from ");
  145. Serial.println(v,DEC);
  146. v=0;
  147. break;
  148. case 'r'://change reverse setting..
  149. if ( userinputreverse[editinput] == true)
  150. {
  151. userinputreverse[editinput]=false;
  152. }
  153. else
  154. {
  155. userinputreverse[editinput]=true;
  156. }
  157. EEPROM.write(editinput,userinputreverse[editinput]);
  158. Serial.print("\n#Reversed input:");
  159. Serial.print(userinputname[editinput]);
  160. Serial.print(" or ");
  161. Serial.print(editinput,DEC);
  162. Serial.print(" is now ");
  163. Serial.println(userinputreverse[editinput],DEC);
  164. break;
  165. case 's'://status..
  166. printstatus();
  167. Serial.println("\n# IN NAME REVERSE MIN MAX VAL PAIR");
  168. for(i=0;USERINPUTS>i;i++)
  169. {
  170. Serial.print("# ");
  171. Serial.print(i,DEC);
  172. Serial.print(" ");
  173. Serial.print(userinputname[i]);
  174. Serial.print(" ");
  175. Serial.print(userinputreverse[i],DEC);
  176. Serial.print(" ");
  177. Serial.print(userinputmin[i]);
  178. Serial.print(" ");
  179. Serial.print(userinputmax[i]);
  180. Serial.print(" ");
  181. Serial.print(userinputval[i],DEC);
  182. Serial.print(" ");
  183. sendvalue(i);
  184. Serial.print("\n");
  185. }
  186. previousMillis=millis()+1000000;
  187. wholestatus=millis()+1000000;
  188. // printstatus();
  189. v=0;
  190. break;
  191. case 'h'://help
  192. Serial.print("\n# Use s to show status.. use e to set input number for modifications by other commands.. like m sets MIN for input value reading. M sets MAX.. r sets reverse toggle or not.\n# example commands:\n# 0e100m1024M0r # this command set input 0's max to 1024 and its min to 0.. and its reverse, it toggled.\n# to set and input's name.. try something like: 0eEz that would set input 0 to the letter z. note numbers and ~ cannot be used. ~ will be ignored. ");
  193. default://eats all invalid input..
  194. // Serial.print("recived unknown command:");
  195. // Serial.print(ch);
  196. while(Serial.available())
  197. {
  198. // Serial.print(Serial.read(),BYTE);
  199. Serial.flush();
  200. }
  201. Serial.flush();
  202. // Serial.println();
  203. v=0;
  204. break;
  205. }//end of case/switch
  206. }
  207. }
  208. //##########################begining of the guts..
  209.  
  210. void setup(void) {
  211. int i,t;
  212. Serial.begin(57600);
  213. Serial.flush();
  214. delay(500);
  215. pinMode(NUNCHUCKPWR1_PIN, OUTPUT); //provides power for joy and buttons..
  216. pinMode(NUNCHUCKPWR2_PIN, OUTPUT); //provides power for joy and buttons..
  217. digitalWrite(NUNCHUCKPWR1_PIN,HIGH);//provides power for joy and buttons..
  218. digitalWrite(NUNCHUCKPWR2_PIN,HIGH);//provides power for joy and buttons..
  219. // pinMode(XBEEPWR1_PIN, OUTPUT); //provides power for Xbee
  220. // pinMode(XBEEPWR2_PIN, OUTPUT); //provides power for Xbee
  221. // digitalWrite(XBEEPWR1_PIN,HIGH);//provides power for Xbee
  222. // digitalWrite(XBEEPWR2_PIN,HIGH);//provides power for Xbee
  223. pinMode(LED_PIN, OUTPUT); //for blinking.
  224. digitalWrite(LED_PIN,HIGH);
  225. Serial.print("#total inputs:");
  226. Serial.println(USERINPUTS,DEC);
  227. for(i=0;USERINPUTS>i;i++)
  228. {
  229. userinputreverse[i]=EEPROM.read(i + OFFSETFORREVERSE);
  230. userinputmin[i]=EEPROM.read(i*2 + OFFSETFORMINS);
  231. userinputmin[i]=userinputmin[i] << 8;
  232. userinputmin[i]=EEPROM.read(i*2 + 1 + OFFSETFORMINS) + userinputmin[i];
  233. userinputmax[i]=EEPROM.read(i*2 + OFFSETFORMAXS);
  234. userinputmax[i]=userinputmax[i] << 8;
  235. userinputmax[i]=EEPROM.read(i*2 + 1 + OFFSETFORMAXS) + userinputmax[i];
  236. //nunchuckfixme userinputlval[i]=analogRead(i);
  237. Serial.print("Input:");
  238. Serial.print(i,DEC);
  239. Serial.print(" Min:");
  240. Serial.print(userinputmin[i],DEC);
  241. Serial.print(" Max:");
  242. Serial.println(userinputmax[i],DEC);
  243. }
  244.  
  245. userinputname[0]='y'; //joy1
  246. userinputname[1]='x'; //joy2
  247. userinputname[2]='~'; //accel1
  248. userinputname[3]='~'; //accel2
  249. userinputname[4]='~'; //accel3
  250. Wire.begin (); // join i2c bus with address 0x52
  251. nunchuck_init (); // send the initilization handshake
  252. }
  253.  
  254. void loop(void) {
  255. int i;
  256. int val;
  257.  
  258. handleserialinput();
  259.  
  260. if (millis() - wholestatus > 1000) //send all values minimal interval.. to keep contact.
  261. {
  262. Serial.println("");//makes debug output formating easier to read.
  263. wholestatus=millis();
  264. digitalWrite(13,ledState=!ledState);
  265. for(i=0;USERINPUTS>i;i++)
  266. {
  267. if (userinputname[i] >= 'a' && userinputname[i] <='z')
  268. {
  269. if ('~' != userinputname[i])
  270. {
  271. sendvalue(i);
  272. previousMillis=millis();
  273. }
  274. }
  275. }
  276. }
  277.  
  278. for(i=0;USERINPUTS>i;i++) //send all values ready to go..
  279. {
  280. if(millis()-previousMillis > 25 )
  281. {//Send the value if its been more then x milliseconds since last send.
  282. if(userinputval[i]-3 > userinputlval[i] || userinputval[i]+3 < userinputlval[i] || userinputval[i] == userinputmin[i] || userinputval[i] == userinputmax[i])
  283. {//send value if its changed more then 3.. or if its hit a min or max.
  284. if(userinputval[i] != userinputlval[i])
  285. { //dont send redundant instructions.
  286. if (userinputname[i] != 0 && '~' != userinputname[i])
  287. { // dont send values with out a good name.
  288. sendvalue(i);
  289. }
  290. // userinputlval[i]=userinputval[i];
  291. }
  292. }
  293. }
  294. }
  295. previousMillis=millis();
  296.  
  297. if (Serial.available() && serialenabled == false)
  298. {
  299. char ch = Serial.read();
  300. if (ch=='$' && Serial.available())
  301. {
  302. ch = Serial.read();
  303. if (ch=='$')
  304. {
  305. serialenabled=true;
  306. Serial.println("\n# Serial enabled");
  307. }
  308. }
  309. else
  310. Serial.flush();
  311. }
  312. Wire.requestFrom (0x52, 6); // request data from nunchuck
  313. while (Wire.available ())
  314. {
  315. outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
  316. cnt++;
  317. }
  318.  
  319. // If we recieved the 6 bytes, then go print them
  320. if (cnt >= 5)
  321. {
  322. populateuserinputvalues();
  323. }
  324.  
  325. cnt = 0;
  326. send_zero (); // send the request for next bytes
  327. delay (100);
  328.  
  329. }
  330.  
  331. void nunchuck_init ()
  332. {
  333. Wire.beginTransmission (0x52); // transmit to device 0x52
  334. Wire.send (0x40); // sends memory address
  335. Wire.send (0x00); // sends sent a zero.
  336. Wire.endTransmission (); // stop transmitting
  337. }
  338.  
  339. void send_zero ()
  340. {
  341. Wire.beginTransmission (0x52); // transmit to device 0x52
  342. Wire.send (0x00); // sends one byte
  343. Wire.endTransmission (); // stop transmitting
  344. }
  345.  
  346. // Print the input data we have recieved
  347. // accel data is 10 bits long
  348. // so we read 8 bits, then we have to add
  349. // on the last 2 bits. That is why I
  350. // multiply them by 2 * 2
  351. void populateuserinputvalues ()
  352. {
  353. int joy_x_axis = outbuf[0];
  354. int joy_y_axis = outbuf[1];
  355. int accel_x_axis = outbuf[2] * 2 * 2;
  356. int accel_y_axis = outbuf[3] * 2 * 2;
  357. int accel_z_axis = outbuf[4] * 2 * 2;
  358.  
  359. int z_button = 0;
  360. int c_button = 0;
  361.  
  362. // byte outbuf[5] contains bits for z and c buttons
  363. // it also contains the least significant bits for the accelerometer data
  364. // so we have to check each bit of byte outbuf[5]
  365. if ((outbuf[5] >> 0) & 1)
  366. {
  367. z_button = 1;
  368. }
  369. if ((outbuf[5] >> 1) & 1)
  370. {
  371. c_button = 1;
  372. }
  373.  
  374. if ((outbuf[5] >> 2) & 1)
  375. {
  376. accel_x_axis += 2;
  377. }
  378. if ((outbuf[5] >> 3) & 1)
  379. {
  380. accel_x_axis += 1;
  381. }
  382.  
  383. if ((outbuf[5] >> 4) & 1)
  384. {
  385. accel_y_axis += 2;
  386. }
  387. if ((outbuf[5] >> 5) & 1)
  388. {
  389. accel_y_axis += 1;
  390. }
  391.  
  392. if ((outbuf[5] >> 6) & 1)
  393. {
  394. accel_z_axis += 2;
  395. }
  396. if ((outbuf[5] >> 7) & 1)
  397. {
  398. accel_z_axis += 1;
  399. }
  400.  
  401. userinputval[0]=joy_x_axis;
  402. userinputval[1]=joy_y_axis;
  403. userinputval[2]=accel_x_axis;
  404. userinputval[3]=accel_y_axis;
  405. userinputval[4]=accel_z_axis;
  406. // userinputzbutton=z_button;
  407. if (z_button)
  408. {
  409. userinputname[0]='y';
  410. userinputname[2]='~';
  411. }
  412. else {
  413. userinputname[0]='~';
  414. userinputname[2]='y';
  415. }
  416. // userinputcbutton=c_button
  417. }
  418.  
  419. // Encode data to format that most wiimote drivers except
  420. // only needed if you use one of the regular wiimote drivers
  421. char nunchuk_decode_byte (char x)
  422. {
  423. x = (x ^ 0x17) + 0x17;
  424. return x;
  425. }
  426.  
  427. //##################### not really used...
  428. void printstatus(void) {
  429. return;//remove for debug..
  430. int i;
  431. Serial.println("#Here is my current status, Thanks for asking:");
  432. for(i=0;USERINPUTS>=i;i++)
  433. {
  434. Serial.print(" pin ");
  435. Serial.print(i,DEC);
  436. Serial.print(":");
  437. sendvalue(i);
  438. Serial.print(" of ");
  439. Serial.print(userinputmin[i],DEC);
  440. Serial.print(",");
  441. Serial.println(userinputmax[i],DEC);
  442. }
  443. }
  444.  
  445. void calibrateuserinputs(void) {
  446. return; //exit's right away.. castrating this function till needed.
  447. int t,i;
  448. for(i=0;USERINPUTS>=i;i++)
  449. {
  450. t=analogRead(i);
  451. if ((t < userinputmin[i]) || (userinputmin[i]==0))
  452. userinputmin[i]=t;
  453. if ((t > userinputmax[i]) || (userinputmax[i]==0))
  454. userinputmax[i]=t;
  455. delay(30);
  456. }
  457. }
Add Comment
Please, Sign In to add comment