Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* ATDserv
- Created by Dustin Reynolds at Mecharobotics.wordpress.com
- You may share this library with Creative Commons - Share Alike
- license 2.0.
- This is released via the Creative Commons Share Alike 2.0 license:
- http://creativecommons.org/licenses/by-sa/2.0/
- You can copy it and use it in whatever, just attribute my name,
- Dustin Reynolds, and my blog when you do.
- I'll appreciate if you let me know that you've used it,
- so I can show off your project on my blog :)
- Copyright 2012 Dustin Reynolds
- *****************************************************************************
- Includes the following:
- BTM-182 connected to pins 7 and 8
- microSD adapter (using old microSD to SD converter)
- Size comparisons:
- Recommended Flags enabled:
- Circuit: Description of the circuit Textually:
- 3.3v VReg (MCP1702-3302E)
- 1-GND
- 2- + of battery, 0.1u to gnd*
- 3-3.3v, 0.1u*
- *-1uF across 3.3V and gnd, 0.1 accross 3.3v and gnd
- ATMEGA328
- 1-connected to Pin 6 of FTDI cable
- 2-Connected to pin 4 of FTDI Cable, Pin 9 of BTM-182 BT serial module(through a 1k resistor), 10k pullup
- 3-Connected to pin 5 of FTDI cable, Pin 10 of BTM-182 BT serial module (through a 1k resistor)
- http://www.billporter.info/how-to-add-multiple-uart-connections/
- 4-NC
- 5-NC
- 6-NC
- 7-3.3V
- 8-gnd
- 9-left lead of 16MHz resonator (center to gnd)
- 10-right lead of 16MHz resonator(center to gnd)
- 11-NC
- 12-NC
- 13-NC
- 14-NC
- 15-NC
- 16-NC
- 17-NC
- 18-NC
- 19-NC
- 20-3.3V
- 21-3.3V
- 22-GND
- 23-NC
- 24-NC
- 25-NC
- 26-NC
- 27-NC
- 28- 1 lead of NTC thermistor (other lead to gnd), 10K resistor to 3.3v
- BTM-182 BT serial module
- http://www.sparkfun.com/products/9913
- AT commands:http://www.robot-r-us.com/downloads/sparkfun/wigwrl/812-wrl09977-lm400-data-sheet-dss-ver-1-2/download.html
- 9-pin 2 of mcu
- 10-pin 3 of mcu
- 15-3.3v
- 16-gnd
- BT using HW serial
- entire system at 3.3v
- Notes:
- After programming, the FTDI cable will need to be removed, since it interfers with
- BT communication(with the TX/RX lines, not the wireless)
- Dustin Reynolds
- 2012-04-19
- */
- #include <Wire.h>
- #include <SoftwareSerial.h>
- #include <SD.h>
- #include <avr/pgmspace.h>
- #include <EEPROM.h>
- #include <Servo.h>
- //Comment out these to disable specific features. Won't disable menus, since that is complicated
- #define BT_ENABLE
- #define BT 1
- //#define SD_ENABLE
- #define FILENAME_OFFSET 20 //single byte stored in EEPROM
- #define THIS_ID ADC_MONITOR_ID
- #define CONTROL_ID 100 //d <-ascii for 100
- #define RC_CAR_ID 101 //e
- #define ADC_MONITOR_ID 102 //f
- //types
- #define TYPE_UTHERE 0
- #define TYPE_DISPTHIS 1
- #define TYPE_NUN_CONTROL 2
- #define TYPE_PS2_CONTROL 3
- #define TYPE_END_COMM 253
- #define TYPE_ACK 254
- #define TYPE_ERROR 255
- #define MAX_PKT_SIZE 30
- //options
- #define OPTION_SEND_CTL 0x01
- #define OPTION_NUN_CTL 0x02
- #define OPTION_PS2_CTL 0x04
- #define TIMEOUT 10
- #define SUCCESS 1
- #define FAILURE 0
- File logFile;
- #define SDCHIPSEL 10
- Servo drive;
- Servo steer;
- //#define DEBUG 1
- #ifdef BT_ENABLE
- //SoftwareSerial btser(7, 8);
- #endif
- const prog_char PROGMEM ppplus[] = "+++";
- const prog_char PROGMEM sm1[] = "ATSM1,ST3E8,SO1";
- const prog_char PROGMEM wncn[] = "ATWN,CN";
- const prog_char PROGMEM atr0[] = "ATR0";
- const prog_char PROGMEM ath[] = "ATH";
- const prog_char PROGMEM atf[] = "ATF?";
- const prog_char PROGMEM atd[] = "ATD";
- const prog_char PROGMEM ata[] = "ATA";
- const prog_char PROGMEM ato[] = "ATO";
- const prog_char PROGMEM Timeout[] = "TimeOut";
- const prog_char PROGMEM Exit[] = "Exit";
- //******************************************************************************
- //
- // Button Definitions
- //
- //******************************************************************************
- //2-dimensional array for asigning the buttons and there high and low values
- const uint16_t PROGMEM Button[21][3] = {{1, 834, 845}, // button 1
- {2, 712, 721}, // button 2
- {3, 603, 613}, // button 3
- {4, 315, 326}, // button 4
- {5, 173, 185}, // button 5
- {6, 85, 97}, // button 6
- {7, 888, 898}, // button 1 + button 2
- {8, 872, 882}, // button 1 + button 3
- {9, 849, 858}, // button 1 + button 4
- {10, 844, 848}, // button 1 + button 5
- {11, 838, 843}, // button 1 + button 6
- {12, 805, 815}, // button 2 + button 3
- {13, 748, 758}, // button 2 + button 4
- {14, 729, 740}, // button 2 + button 5
- {15, 719, 728}, // button 2 + button 6
- {16, 668, 678}, // button 3 + button 4
- {17, 636, 646}, // button 3 + button 5
- {18, 619, 629}, // button 3 + button 6
- {19, 405, 415}, // button 4 + button 5
- {20, 359, 369}, // button 4 + button 6
- {21, 237, 247}}; // button 5 + button 6
- int setup_ser(byte ser, char * string, char init, char initcr,char justppp, unsigned long timeout, uint16_t analogpin);
- uint8_t buttonWait(uint16_t analogpin, uint8_t toggle, uint8_t hold);
- uint8_t buttonCheck( uint16_t analogpin);
- int send_pkt(byte iface, byte dest, byte type, int count, char * buffer)
- {
- int checksum;
- //X
- Serial.write(0x0a); //LF
- Serial.write(dest);
- //Y
- Serial.write(THIS_ID);//100 is controller
- //Z Type
- Serial.write(type);
- //A count
- Serial.write(count);
- //intialize checksum
- checksum = dest+THIS_ID+type+count;
- //get checksum for data
- for(int j=0; j<count; j++)
- checksum +=buffer[j];
- //send data
- for(int j=0; j<count; j++)
- Serial.write(buffer[j]);
- while (checksum > 256)
- checksum -= 256;
- Serial.write(checksum);
- Serial.write(0x0d); //LF
- return 1;
- }
- byte get_pkt(byte iface, char* buffer, byte size, uint16_t timeout)
- {
- byte temp;
- byte gotchar = 0;
- byte type;
- byte count = 0;
- byte checksum = 0;
- byte theirchecksum = 0;
- byte theirid;
- byte buffoffset = 0;
- byte state = 0; //0 - wait for LF
- //1 - next is THIS_ID
- //2 - their ID
- //3 - type
- //4 - count
- //5-count - packet
- //last checksum
- unsigned long time1 = millis();
- while(1){
- if(millis() > time1 + timeout)
- {
- //timeout, abort
- memset(buffer, 0, size);
- return TIMEOUT;
- }
- gotchar = 0; //only iterate on times in which we received something
- //don't want to be stuck in 1 big if statement though
- if(Serial.available())
- {
- temp = Serial.read();
- gotchar = 1;
- }
- if(gotchar == 0)
- continue;
- //state machine
- if(state == 0)
- {
- if(temp == 0x0A) //only start processing iff LF received
- {
- state++;
- }
- }
- else if(state == 1)
- {
- if(temp == THIS_ID)
- {
- state++;
- checksum += THIS_ID;
- }
- else
- {
- state = 0;
- count = 0;
- checksum = 0;
- buffoffset = 0;
- }
- }
- else if(state == 2)
- {
- theirid = temp;
- checksum += temp;
- state++;
- *(buffer + buffoffset++) = theirid;
- }
- else if(state == 3)
- {
- type = temp; //save type, not sure what to do with it now
- checksum += type;
- state++;
- *(buffer + buffoffset++) = type;
- }
- else if(state == 4)
- {
- count = temp; //save count
- checksum += count;
- if(count == 0) //empty packet?
- state++; //skip packet step, go straight to checksum
- state++;
- *(buffer + buffoffset++) = count;
- }
- else if(state == 5)
- {
- //stay in this state until count bytes arrive, or until timeout
- //count guaranteed to be > 0 initially
- *(buffer + buffoffset++) = temp; //save in buffer
- checksum += temp;
- if(--count == 0)
- {
- state++;
- }
- }
- else if(state == 6)
- {
- //checksum
- theirchecksum = temp;
- if(theirchecksum == checksum)
- {
- //Buffer valid, return to calling program
- return SUCCESS; //data stored in provided buffer
- }
- else
- {
- //checksum not valid, return to state 0
- state = 0;
- memset(buffer, 0, size);
- }
- }
- }
- }
- //buffer must be at least 5 big
- //
- // offset starts at 5, goes down as the number is larger
- // so that it is right aligned
- byte convert_string(char * string, short n)
- {
- byte count = 0;
- if(n>=10)
- {
- count = convert_string(string, n/10);
- n = n%10;
- }
- *(string + count) = n+'0';
- return count+1;
- }
- /* Handle packet - Does everything conceivable for a received packet
- -handles control data from controller
- -sends updated ATD measurements
- */
- byte handle_pkt(byte iface, byte dest, byte options, uint16_t sendctl, uint16_t timeout)
- {
- unsigned long time_timeout = millis() + timeout;
- unsigned long time_sendctl = millis() + sendctl;
- char buffer[MAX_PKT_SIZE];
- char outbuffer[MAX_PKT_SIZE];
- byte thisdest;
- byte type;
- byte nthings;
- byte col;
- byte row;
- byte val;
- byte error;
- byte zbutton, cbutton, joy_x,joy_y;
- int temp;
- int tempx,tempy,tempz;
- int i = 0;
- while(1)
- {
- //update device, if we are using it
- if(millis() > time_timeout)
- {
- //break;
- }
- if(millis() > time_sendctl)
- {
- if(options & OPTION_SEND_CTL)
- {
- memset(buffer,0,MAX_PKT_SIZE);
- i = 0;
- //get packet ready to send
- //clear display
- send_pkt(BT, CONTROL_ID, TYPE_DISPTHIS,0,buffer);
- type = TYPE_DISPTHIS;
- buffer[i++] = 0; //row;
- buffer[i++] = 0; //col
- strncpy(buffer+i,"volt:", 20); //max of 1 row at a time, received string
- i=7;
- temp = analogRead(A5);
- i+=convert_string(&buffer[i], temp);
- send_pkt(BT, CONTROL_ID, TYPE_DISPTHIS,i,buffer);
- }
- time_sendctl = millis() + sendctl;
- }
- error = get_pkt(iface, buffer, MAX_PKT_SIZE, 1000); //longer delay since not actively controlling something
- //process packet
- //if(error == TIMEOUT)
- // send_pkt(iface,dest,TYPE_ERROR,0,buffer);
- if(error == SUCCESS)
- {
- i = 0;
- //their id
- thisdest = buffer[i++];
- if(thisdest!= dest)
- {
- //should we process this? leave it for now
- }
- else
- {
- //reset time, since we recently received something.
- time_timeout = millis() + timeout;
- }
- //read type
- type = buffer[i++];
- memset(outbuffer,0,sizeof(outbuffer));
- switch(type)
- {
- case TYPE_UTHERE:
- {
- nthings = buffer[i++];
- outbuffer[0] = 'Y';
- if(buffer[i] == 'P')
- send_pkt(iface,thisdest,TYPE_UTHERE,1,outbuffer);
- //else, do nothing, no response needed
- break;
- }
- case TYPE_DISPTHIS:
- {
- //disp can be on controller, or remote thing!
- break;
- }
- case TYPE_NUN_CONTROL:
- {
- //use joy_x and joy_y to control servos
- //data is in buffer
- nthings = buffer[i++];
- zbutton = buffer[i++];
- cbutton = buffer[i++];
- joy_x = buffer[i++];
- joy_y = buffer[i++];
- tempx = buffer[i++] << 8;
- tempx += buffer[i++];
- tempy = buffer[i++] << 8;
- tempy += buffer[i++];
- tempz = buffer[i++] << 8;
- tempz += buffer[i++];
- //now have everything, turn servos now
- joy_x = map(joy_x, 0, 255, 0, 179);
- joy_y = map(joy_y, 0, 255, 0, 179);
- drive.write(joy_x);
- steer.write(joy_y);
- break;
- }
- case TYPE_PS2_CONTROL:
- {
- //for controller, what does this mean?
- break;
- }
- case TYPE_ACK:
- {
- //last packet received OK
- break;
- }
- case TYPE_ERROR:
- {
- //last packet not received, resend depending on mode perhaps?
- break;
- }
- case TYPE_END_COMM:
- {
- //remote requests end of comm
- send_pkt(iface,thisdest,TYPE_END_COMM,0,outbuffer);//send packet acking this
- break;
- }
- default:
- {
- //future type?
- break;
- }
- }
- }
- //exit condition?
- if(analogRead(A0) > 70)
- {
- while(analogRead(A0) > 70){};
- break;
- }
- }
- }
- void setup()
- {
- #ifdef BT_ENABLE
- Serial.begin(9600);
- #endif
- #ifdef SD_ENABLE
- pinMode(10, OUTPUT);
- #endif
- drive.attach(2);
- steer.attach(3);
- }
- void loop()
- {
- byte options = 0;
- options = OPTION_SEND_CTL | OPTION_NUN_CTL;
- handle_pkt(BT, CONTROL_ID, options, 100, 20000);
- }
- int setup_ser(byte ser, PGM_P PROGMEM string, char init, char initcr, char justppp, unsigned long timeout,uint16_t analogpin)
- {
- char state=0, temp;
- //unsigned long time1 = millis();
- if(init){
- Serial.print((__FlashStringHelper *)ppplus);
- if(initcr)
- Serial.write(0x0D);
- }
- else
- state = 3;
- while(1)
- {
- if(state == 3)
- {
- state++;
- if(justppp)
- continue;
- Serial.print((__FlashStringHelper *)string);
- Serial.write(0x0D);
- delay(100);
- }
- if(Serial.available())
- {
- temp = Serial.read();
- if(temp == 0x0D)
- {
- state++;
- continue;
- }
- if(temp == 'O')
- state++;
- if(temp == 'K')
- state++;
- //if(temp == 'E' || temp == 'R')
- // return 0; //error
- }
- if(analogRead(analogpin) > 70)
- {
- while(analogRead(analogpin) > 70){};
- return 0;
- }
- }
- return 1;
- }
- //reserved for future
- #if 0
- int scan_bt_menuize(byte timeout)
- {
- char state=0, temp, skip, devicenum;
- char sindex[20];
- char buffer[10][20];
- char mac[10][15];
- unsigned long time1 = millis();
- lcd.clear();
- //send ATF?
- Serial.print((__FlashStringHelper *)atf); //ATF?
- Serial.write(0x0D);
- //create own menu system here, pretty much. Need to be able to select, and connect to it
- while(skip < 25) //17
- {
- if(Serial.available())
- {
- temp = Serial.read();
- //lcd.print((char)temp);
- //delay(250);
- skip++;
- }
- //if(millis() > time1 + timeout)
- //{
- // lcd.print((__FlashStringHelper *)Timeout);
- // delay(1000);
- // break;
- //}
- if(analogRead(A0) > 70)
- return 0;
- }
- //process each result from BT module, displaying it as you go
- while(1)
- {
- temp = 0;
- int i = 0; //cnt of number of BT things around
- skip = 0;
- while(skip < 3) //skip LF and first number. Land in space region before name
- {
- if(Serial.available())
- {
- temp = Serial.read();
- //lcd.print((char)temp);
- skip++;
- }
- if(analogRead(A0) > 70)
- return 0;
- }
- //now read spaces until nonspace
- while(temp == ' ')
- {
- if(Serial.available())
- {
- temp = Serial.read();
- //lcd.print((char)temp);
- }
- if(analogRead(A0) > 70)
- return 0;
- }
- //lcd.clear();
- //lcd.print("proc Name");lcd.print((int)devicenum);
- //lcd.setCursor(0,1);
- //Now process this name
- buffer[devicenum][i++] = temp;
- //lcd.print((char)temp);
- while(temp != ' ')
- {
- if(Serial.available())
- {
- temp = Serial.read();
- //lcd.print((char)temp);
- //delay(250);
- if(temp != ' ')
- buffer[devicenum][i++]=temp; //save name
- }
- //if(analogRead(A0) > 70)
- // return 0;
- if(analogRead(A0) > 70)
- {
- lcd.print((int)i);
- while(analogRead(A0) > 70){};
- //return 0;
- }
- }
- buffer[devicenum][i] = 0; //null terminated
- //delay(2000);
- //lcd.clear();
- //lcd.print("remove space");
- //lcd.setCursor(0,1);
- //now read spaces until nonspace
- while(temp == ' ')
- {
- if(Serial.available())
- {
- temp = Serial.read();
- //lcd.print((char)temp);
- }
- if(analogRead(A0) > 70)
- return 0;
- }
- i=0;
- //delay(2000);
- //lcd.clear();
- //lcd.print("proc Mac");
- //lcd.setCursor(0,1);
- //now BT mac, need to save this too!
- mac[devicenum][i++]=temp; //temp is first nonzero from above
- while(i < 14) //expect XXXX-XX-XXXXXX
- {
- if(Serial.available())
- {
- temp = Serial.read();
- //lcd.print((char)temp);
- //delay(250);
- if(temp != 0x0A) //should never be 0x0A, if it is, we missed a character
- mac[devicenum][i++]=temp; //save name
- }
- if(analogRead(A0) > 70)
- {
- lcd.print((__FlashStringHelper *)Exit);
- while(analogRead(A0) > 70){};
- return 0;
- }
- }
- mac[devicenum][i] = 0;
- //lcd.clear();
- //now we have device name, and mac, both null terminated. Display device name
- lcd.setCursor(1,devicenum); //leave space for cursor
- lcd.print(buffer[devicenum++]); //hopefully it is less than 19 chars long
- delay(1000);
- time1=millis();
- while(millis() < time1 + 4000)
- {
- if(Serial.available())
- {
- temp = Serial.read();
- //lcd.print((char)temp);
- //delay(250);
- break;
- }
- }
- if(millis() < time1 + 4000)
- return 0;
- }
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement