Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //This is an attempt at creating an RC Transmitter and Reciver in a single firmware.. why.. I don't know.
- #include <EEPROM.h>
- #include <Wire.h>
- #include <string.h>
- #undef int
- #include <stdio.h>
- uint8_t outbuf[6]; //array to store nunchuck output
- int cnt = 0; //nunchuck byte recieved counter
- char serialenabled=false;
- long int previousMillis=millis();
- long int previousRefresh=millis();
- long int wholestatus=millis();
- #define USERINPUTS 5
- char userinputname[USERINPUTS];
- int userinputmin[USERINPUTS];
- int userinputmax[USERINPUTS];
- int userinputlval[USERINPUTS];
- int userinputval[USERINPUTS];
- int userinputreverse[USERINPUTS];
- int v=0;
- int editinput=0; // which input is currently in edit mode.
- //EEPROM address mapping: first 4 bytes are reverse settings.
- #define OFFSETFORREVERSE 0
- //after that is min settings.
- #define OFFSETFORMINS OFFSETFORREVERSE + USERINPUTS
- //after that is max settings.
- //#define OFFSETFORMAXS OFFSETFORREVERSE + (OFFSETFORMINS + USERINPUTS * 2)
- #define OFFSETFORMAXS 12
- //Those are each the starting positions in memory for where the array is stored.
- char ledState=0;
- #define LED_PIN 13
- #define XBEEPWR1_PIN 9
- #define XBEEPWR2_PIN 8
- #define NUNCHUCKPWR1_PIN 10
- #define NUNCHUCKPWR2_PIN 11
- void sendvalue(int i)
- {
- userinputlval[i]=userinputval[i];
- if (userinputval[i] < userinputmin[i] || userinputval[i] > userinputmax[i])
- return;
- if (1024 < userinputmin[i] || 0 > userinputmax[i])
- return;
- if (userinputmin[i] > userinputmax[i])
- return;
- if (userinputreverse[i] == false )
- {
- userinputval[i]=map(userinputval[i],userinputmin[i],userinputmax[i],0,180); //180 because of servo's..
- }
- else
- {
- userinputval[i]=map(userinputval[i],userinputmin[i],userinputmax[i],180,0); //180 because of servo's..
- }
- constrain(userinputval[i],0,180);
- Serial.print(userinputval[i],DEC);
- Serial.print(userinputname[i]);
- // Serial.flush();
- digitalWrite(LED_PIN,ledState=!ledState);
- }
- void handleserialinput(void)
- {
- if (Serial.available() && serialenabled == true)
- {
- int i;
- char ch = Serial.read();
- switch(ch) {
- case '0'...'9':
- v = v * 10 + ch - '0';
- break;
- case '$':
- serialenabled=false;
- Serial.println("\n# Serial disabled");
- break;
- case 'e'://set which input to edit.
- if ( v < 0 || v >= USERINPUTS)
- {
- Serial.println("\n#reverse: can't change.. invalid input specified. please use 0-USERINPUTS");
- v=0;
- break;
- }
- editinput=v;
- Serial.print("\n#now we'll edit input ");
- Serial.println(editinput,DEC);
- v=0;
- break;
- case 'E'://edit input name...
- if ( Serial.available())
- v=Serial.read();
- if ( v > '0' && v < '9')
- {
- Serial.println("\n#cannot set input name.. invalid char.");
- v=0;
- break;
- }
- userinputname[editinput]=v;
- Serial.print("\n#input ");
- Serial.print(editinput,DEC);
- Serial.print(" name is now ");
- Serial.println(v);
- v=0;
- break;
- case 'm'://set minimum value exptected from input.
- if ( v < 0 || v > 1024)
- {
- Serial.println("\n#minimum value out of range.. use 0-1024");
- v=0;
- break;
- }
- userinputmin[editinput]=v;
- EEPROM.write(editinput*2+OFFSETFORMINS,v >> 8);
- EEPROM.write(editinput*2+1+OFFSETFORMINS,v);
- v=EEPROM.read(editinput*2+OFFSETFORMINS);
- v=v << 8;
- v=EEPROM.read(editinput*2+1+OFFSETFORMINS) + v;
- Serial.print("\n#Minimum value for input ");
- Serial.print(editinput,DEC);
- Serial.print(" set to ");
- Serial.print(userinputmin[editinput],DEC);
- Serial.print(" from ");
- Serial.println(v,DEC);
- v=0;
- break;
- case 'M'://set maximum value exptected from input.
- if ( v < 0 || v > 1024)
- {
- Serial.println("\n#maximum value out of range.. use 0-1024");
- v=0;
- break;
- }
- userinputmax[editinput]=v;
- EEPROM.write(editinput*2+OFFSETFORMAXS,v >> 8);
- EEPROM.write(editinput*2+1+OFFSETFORMAXS,v);
- v=EEPROM.read(editinput*2+OFFSETFORMAXS);
- v=v << 8;
- v=EEPROM.read(editinput*2+1+OFFSETFORMAXS) + v;
- Serial.print("\n#Maximum value for input ");
- Serial.print(editinput,DEC);
- Serial.print(" set to ");
- Serial.print(userinputmin[editinput],DEC);
- Serial.print(" from ");
- Serial.println(v,DEC);
- v=0;
- break;
- case 'r'://change reverse setting..
- if ( userinputreverse[editinput] == true)
- {
- userinputreverse[editinput]=false;
- }
- else
- {
- userinputreverse[editinput]=true;
- }
- EEPROM.write(editinput,userinputreverse[editinput]);
- Serial.print("\n#Reversed input:");
- Serial.print(userinputname[editinput]);
- Serial.print(" or ");
- Serial.print(editinput,DEC);
- Serial.print(" is now ");
- Serial.println(userinputreverse[editinput],DEC);
- break;
- case 's'://status..
- printstatus();
- Serial.println("\n# IN NAME REVERSE MIN MAX VAL PAIR");
- for(i=0;USERINPUTS>i;i++)
- {
- Serial.print("# ");
- Serial.print(i,DEC);
- Serial.print(" ");
- Serial.print(userinputname[i]);
- Serial.print(" ");
- Serial.print(userinputreverse[i],DEC);
- Serial.print(" ");
- Serial.print(userinputmin[i]);
- Serial.print(" ");
- Serial.print(userinputmax[i]);
- Serial.print(" ");
- Serial.print(userinputval[i],DEC);
- Serial.print(" ");
- sendvalue(i);
- Serial.print("\n");
- }
- previousMillis=millis()+1000000;
- wholestatus=millis()+1000000;
- // printstatus();
- v=0;
- break;
- case 'h'://help
- 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. ");
- default://eats all invalid input..
- // Serial.print("recived unknown command:");
- // Serial.print(ch);
- while(Serial.available())
- {
- // Serial.print(Serial.read(),BYTE);
- Serial.flush();
- }
- Serial.flush();
- // Serial.println();
- v=0;
- break;
- }//end of case/switch
- }
- }
- //##########################begining of the guts..
- void setup(void) {
- int i,t;
- Serial.begin(57600);
- Serial.flush();
- delay(500);
- pinMode(NUNCHUCKPWR1_PIN, OUTPUT); //provides power for joy and buttons..
- pinMode(NUNCHUCKPWR2_PIN, OUTPUT); //provides power for joy and buttons..
- digitalWrite(NUNCHUCKPWR1_PIN,HIGH);//provides power for joy and buttons..
- digitalWrite(NUNCHUCKPWR2_PIN,HIGH);//provides power for joy and buttons..
- // pinMode(XBEEPWR1_PIN, OUTPUT); //provides power for Xbee
- // pinMode(XBEEPWR2_PIN, OUTPUT); //provides power for Xbee
- // digitalWrite(XBEEPWR1_PIN,HIGH);//provides power for Xbee
- // digitalWrite(XBEEPWR2_PIN,HIGH);//provides power for Xbee
- pinMode(LED_PIN, OUTPUT); //for blinking.
- digitalWrite(LED_PIN,HIGH);
- Serial.print("#total inputs:");
- Serial.println(USERINPUTS,DEC);
- for(i=0;USERINPUTS>i;i++)
- {
- userinputreverse[i]=EEPROM.read(i + OFFSETFORREVERSE);
- userinputmin[i]=EEPROM.read(i*2 + OFFSETFORMINS);
- userinputmin[i]=userinputmin[i] << 8;
- userinputmin[i]=EEPROM.read(i*2 + 1 + OFFSETFORMINS) + userinputmin[i];
- userinputmax[i]=EEPROM.read(i*2 + OFFSETFORMAXS);
- userinputmax[i]=userinputmax[i] << 8;
- userinputmax[i]=EEPROM.read(i*2 + 1 + OFFSETFORMAXS) + userinputmax[i];
- //nunchuckfixme userinputlval[i]=analogRead(i);
- Serial.print("Input:");
- Serial.print(i,DEC);
- Serial.print(" Min:");
- Serial.print(userinputmin[i],DEC);
- Serial.print(" Max:");
- Serial.println(userinputmax[i],DEC);
- }
- userinputname[0]='y'; //joy1
- userinputname[1]='x'; //joy2
- userinputname[2]='~'; //accel1
- userinputname[3]='~'; //accel2
- userinputname[4]='~'; //accel3
- Wire.begin (); // join i2c bus with address 0x52
- nunchuck_init (); // send the initilization handshake
- }
- void loop(void) {
- int i;
- int val;
- handleserialinput();
- if (millis() - wholestatus > 1000) //send all values minimal interval.. to keep contact.
- {
- Serial.println("");//makes debug output formating easier to read.
- wholestatus=millis();
- digitalWrite(13,ledState=!ledState);
- for(i=0;USERINPUTS>i;i++)
- {
- if (userinputname[i] >= 'a' && userinputname[i] <='z')
- {
- if ('~' != userinputname[i])
- {
- sendvalue(i);
- previousMillis=millis();
- }
- }
- }
- }
- for(i=0;USERINPUTS>i;i++) //send all values ready to go..
- {
- if(millis()-previousMillis > 25 )
- {//Send the value if its been more then x milliseconds since last send.
- if(userinputval[i]-3 > userinputlval[i] || userinputval[i]+3 < userinputlval[i] || userinputval[i] == userinputmin[i] || userinputval[i] == userinputmax[i])
- {//send value if its changed more then 3.. or if its hit a min or max.
- if(userinputval[i] != userinputlval[i])
- { //dont send redundant instructions.
- if (userinputname[i] != 0 && '~' != userinputname[i])
- { // dont send values with out a good name.
- sendvalue(i);
- }
- // userinputlval[i]=userinputval[i];
- }
- }
- }
- }
- previousMillis=millis();
- if (Serial.available() && serialenabled == false)
- {
- char ch = Serial.read();
- if (ch=='$' && Serial.available())
- {
- ch = Serial.read();
- if (ch=='$')
- {
- serialenabled=true;
- Serial.println("\n# Serial enabled");
- }
- }
- else
- Serial.flush();
- }
- Wire.requestFrom (0x52, 6); // request data from nunchuck
- while (Wire.available ())
- {
- outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer
- cnt++;
- }
- // If we recieved the 6 bytes, then go print them
- if (cnt >= 5)
- {
- populateuserinputvalues();
- }
- cnt = 0;
- send_zero (); // send the request for next bytes
- delay (100);
- }
- void nunchuck_init ()
- {
- Wire.beginTransmission (0x52); // transmit to device 0x52
- Wire.send (0x40); // sends memory address
- Wire.send (0x00); // sends sent a zero.
- Wire.endTransmission (); // stop transmitting
- }
- void send_zero ()
- {
- Wire.beginTransmission (0x52); // transmit to device 0x52
- Wire.send (0x00); // sends one byte
- Wire.endTransmission (); // stop transmitting
- }
- // Print the input data we have recieved
- // accel data is 10 bits long
- // so we read 8 bits, then we have to add
- // on the last 2 bits. That is why I
- // multiply them by 2 * 2
- void populateuserinputvalues ()
- {
- int joy_x_axis = outbuf[0];
- int joy_y_axis = outbuf[1];
- int accel_x_axis = outbuf[2] * 2 * 2;
- int accel_y_axis = outbuf[3] * 2 * 2;
- int accel_z_axis = outbuf[4] * 2 * 2;
- int z_button = 0;
- int c_button = 0;
- // byte outbuf[5] contains bits for z and c buttons
- // it also contains the least significant bits for the accelerometer data
- // so we have to check each bit of byte outbuf[5]
- if ((outbuf[5] >> 0) & 1)
- {
- z_button = 1;
- }
- if ((outbuf[5] >> 1) & 1)
- {
- c_button = 1;
- }
- if ((outbuf[5] >> 2) & 1)
- {
- accel_x_axis += 2;
- }
- if ((outbuf[5] >> 3) & 1)
- {
- accel_x_axis += 1;
- }
- if ((outbuf[5] >> 4) & 1)
- {
- accel_y_axis += 2;
- }
- if ((outbuf[5] >> 5) & 1)
- {
- accel_y_axis += 1;
- }
- if ((outbuf[5] >> 6) & 1)
- {
- accel_z_axis += 2;
- }
- if ((outbuf[5] >> 7) & 1)
- {
- accel_z_axis += 1;
- }
- userinputval[0]=joy_x_axis;
- userinputval[1]=joy_y_axis;
- userinputval[2]=accel_x_axis;
- userinputval[3]=accel_y_axis;
- userinputval[4]=accel_z_axis;
- // userinputzbutton=z_button;
- if (z_button)
- {
- userinputname[0]='y';
- userinputname[2]='~';
- }
- else {
- userinputname[0]='~';
- userinputname[2]='y';
- }
- // userinputcbutton=c_button
- }
- // Encode data to format that most wiimote drivers except
- // only needed if you use one of the regular wiimote drivers
- char nunchuk_decode_byte (char x)
- {
- x = (x ^ 0x17) + 0x17;
- return x;
- }
- //##################### not really used...
- void printstatus(void) {
- return;//remove for debug..
- int i;
- Serial.println("#Here is my current status, Thanks for asking:");
- for(i=0;USERINPUTS>=i;i++)
- {
- Serial.print(" pin ");
- Serial.print(i,DEC);
- Serial.print(":");
- sendvalue(i);
- Serial.print(" of ");
- Serial.print(userinputmin[i],DEC);
- Serial.print(",");
- Serial.println(userinputmax[i],DEC);
- }
- }
- void calibrateuserinputs(void) {
- return; //exit's right away.. castrating this function till needed.
- int t,i;
- for(i=0;USERINPUTS>=i;i++)
- {
- t=analogRead(i);
- if ((t < userinputmin[i]) || (userinputmin[i]==0))
- userinputmin[i]=t;
- if ((t > userinputmax[i]) || (userinputmax[i]==0))
- userinputmax[i]=t;
- delay(30);
- }
- }
Add Comment
Please, Sign In to add comment