├── LICENSE ├── README.md ├── alarmClock ├── alarmClock │ └── alarmClock.ino └── testPCF8563 │ └── testPCF8563.ino ├── chattingUsingEvive ├── chattingUsingEvive │ └── chattingUsingEvive.ino └── testESPv2 │ └── testESPv2.ino ├── imageToFlashMemoryIconsForTFT ├── images │ ├── battery.bmp │ ├── bell.bmp │ ├── evive_in_hand.jpg │ ├── evive_logo.bmp │ ├── semiCircle.bmp │ ├── user.bmp │ └── wifi.bmp └── tftIcons │ ├── bitmaps.h │ ├── bitmapsLarge.h │ └── tftIcons.ino ├── lineFollow1Sheeld └── lineFollow1Sheeld.ino ├── mobileMicroscope └── STL files │ ├── Bottom.stl │ ├── FocussingScrews.stl │ ├── SlideHolder.stl │ └── Top.stl ├── obstacleAvoidanceRobot ├── Servo │ ├── README.adoc │ ├── examples │ │ ├── Knob │ │ │ └── Knob.ino │ │ └── Sweep │ │ │ └── Sweep.ino │ ├── keywords.txt │ ├── library.properties │ └── src │ │ ├── Servo.h │ │ ├── avr │ │ ├── Servo.cpp │ │ └── ServoTimers.h │ │ ├── sam │ │ ├── Servo.cpp │ │ └── ServoTimers.h │ │ └── samd │ │ ├── Servo.cpp │ │ └── ServoTimers.h ├── motor │ ├── motor.cpp │ └── motor.h └── obstacleAvoidance │ └── obstacleAvoidance.ino ├── olympicsCountDownTimer ├── Rio.jpg ├── Rio2016_gif.gif ├── Rio_gif.gif ├── logoOlympicsRio2016.jpg ├── logoOlympicsRio2016ForTFT.jpg └── olympicsCountDownTimer │ ├── bitmaps.h │ ├── bitmapsLarge.h │ └── olympicsCountDownTimer.ino ├── pianoScratch └── pianoOnEviveUsingScratch.sb2 ├── plantMonitoringSystem └── plantMonitoringSystem.ino ├── projectDocumentation ├── homeAutomation_V2.pdf ├── modularRobot_V2.pdf ├── roboticArm_V2.pdf └── starterKit_V2.pdf ├── scientificCalculator └── scientificCalculator.ino ├── simonSaysGame └── simonSaysGame.ino ├── skateboard ├── motor │ ├── motor.cpp │ └── motor.h └── skateboard │ └── skateboard.ino └── twitterKeypad ├── Keypad ├── Keypad.cpp ├── Keypad.h ├── examples │ ├── CustomKeypad │ │ └── CustomKeypad.ino │ ├── DynamicKeypad │ │ └── DynamicKeypad.ino │ ├── EventKeypad │ │ └── EventKeypad.ino │ ├── HelloKeypad │ │ └── HelloKeypad.ino │ ├── HelloKeypad3 │ │ └── HelloKeypad3.ino │ ├── MultiKey │ │ └── MultiKey.ino │ └── loopCounter │ │ └── loopCounter.ino ├── keywords.txt └── utility │ ├── Key.cpp │ └── Key.h └── twitterKeypad └── twitterKeypad.ino /LICENSE: -------------------------------------------------------------------------------- 1 | License Information 2 | This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. 3 | All codes are open source so please feel free to do anything you want with it under the terms mentioned at https://creativecommons.org/licenses/by-sa/4.0/legalcode. 4 | Remember to give attrubution to "evivetoolkit" for using this. 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eviveProjects 2 | evive team and lots of makers contribute to create an opensource pool of ideas and projects. If you want to contribute any projects, please write us at contact@evive.cc. 3 | -------------------------------------------------------------------------------- /alarmClock/alarmClock/alarmClock.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Alarm clock using evive 3 | * Developed by: Madhukant and Tushar Gupta 4 | * Date: 2016/05/30 5 | * 6 | * NOTE: After uploading this code once to set time-date-day-etc, comment out the 7 | * line number 124 (setPCF8563();) and upload again. The calender data will be stored 8 | * in RTC (real time clock: PCF8563) even after reset. 9 | * 10 | * Tutorial link: http://www.instructables.com/id/Alarm-Clock-With-Evive/ 11 | * Vidoe Link: https://www.youtube.com/watch?v=oMFPtdQXw4E&feature=youtu.be 12 | */ 13 | 14 | #include // Core graphics library 15 | #include // Hardware-specific library 16 | #include 17 | 18 | // For the breakout, you can use any 2 or 3 pins 19 | // These pins will also work for the 1.8" TFT shield 20 | // TFT is internally connected to Arduino MEGA in evive 21 | #define TFT_CS 48 22 | #define TFT_RST 47 23 | #define TFT_DC 49 24 | 25 | //initialize a tft variable 26 | Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 27 | 28 | //********************alarm clock initiasation*********************** 29 | #include "Wire.h" 30 | #define PCF8563address 0x51 31 | 32 | #define alarmOnOff 40 33 | #define alarmHand A9 34 | #define buzzerPin 46 35 | // calender function variables 36 | byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 37 | String days[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; 38 | 39 | // Bell icon size: 16W*16H 40 | const unsigned char bell [] PROGMEM = { 41 | 0x01, 0x80, 0x03, 0xc0, 0x0f, 0xf0, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 42 | 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0x3f, 0xfc, 43 | }; 44 | 45 | byte bcdToDec(byte value) 46 | { 47 | return ((value / 16) * 10 + value % 16); 48 | } 49 | 50 | byte decToBcd(byte value){ 51 | return (value / 10 * 16 + value % 10); 52 | } 53 | 54 | void setPCF8563() 55 | // this sets the time and date to the PCF8563 56 | { 57 | Wire.beginTransmission(PCF8563address); 58 | Wire.write(0x02); 59 | Wire.write(decToBcd(second)); //second 60 | Wire.write(decToBcd(minute)); //minute 61 | Wire.write(decToBcd(hour)); //hour 62 | Wire.write(decToBcd(dayOfMonth)); //date 63 | Wire.write(decToBcd(dayOfWeek)); //day of week see_the_above array 64 | Wire.write(decToBcd(month)); //month 65 | Wire.write(decToBcd(year)); //year 66 | Wire.endTransmission(); 67 | } 68 | 69 | // Gets the time and date from the PCF8563 70 | void readPCF8563() 71 | { 72 | Wire.beginTransmission(PCF8563address); 73 | Wire.write(0x02); 74 | Wire.endTransmission(); 75 | Wire.requestFrom(PCF8563address, 7); 76 | second = bcdToDec(Wire.read() & B01111111); // remove VL error bit 77 | minute = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB 78 | hour = bcdToDec(Wire.read() & B00111111); 79 | dayOfMonth = bcdToDec(Wire.read() & B00111111); 80 | dayOfWeek = bcdToDec(Wire.read() & B00000111); 81 | month = bcdToDec(Wire.read() & B00011111); // remove century bit, 1999 is over 82 | year = bcdToDec(Wire.read()); 83 | } 84 | 85 | //Initialize angles of clock hands 86 | float hangle=0; 87 | float mangle=0; 88 | float sangle=0; 89 | float aangle=0,paangle=0; 90 | 91 | int i=0; 92 | 93 | void setup() 94 | { 95 | //*************************clock setup***************** 96 | tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab 97 | 98 | tft.fillScreen(ST7735_BLACK); 99 | //Draw clock dial and hour markings 100 | tft.drawCircle(tft.width()/2,tft.height()/2,60,ST7735_WHITE); 101 | for(i=0;i<12;i++) 102 | { 103 | tft.drawLine(tft.width()/2+55*sin(i*30*3.14/180),tft.height()/2+55*cos(i*30*3.14/180),tft.width()/2+60*sin(i*30*3.14/180),tft.height()/2+60*cos(i*30*3.14/180),ST7735_WHITE); 104 | } 105 | Serial.println("init"); 106 | tft.setRotation(1); 107 | tft.setTextWrap(false); // Allow text to run off right edge 108 | //tft.fillScreen(ST7735_BLACK); 109 | //***************clock setup end ********************** 110 | Wire.begin(); 111 | Serial.begin(9600); 112 | pinMode(alarmOnOff,INPUT); 113 | 114 | //Change the following to set your initial time 115 | second = 0; //0-59 116 | minute = 0; //0-59 117 | hour = 0; //0-23 118 | dayOfWeek = 0; //0-6 119 | dayOfMonth = 1; //1-31 (includes Leap year correction by having 29th Feb) 120 | month = 1; //1-12 121 | year = 0; //0-99 122 | 123 | //Comment out the next line and upload again to set and keep the time from resetting every reset 124 | setPCF8563(); 125 | 126 | // int alarmpot=A9; 127 | //pinMode(39,INPUT); 128 | pinMode(buzzerPin,OUTPUT); 129 | } 130 | 131 | //**************variables for tone******************************* 132 | int songLength = 18; 133 | char notes[] = "cdfda ag cdfdg gf "; 134 | int beats[] = {1,1,1,1,1,1,4,4,2,1,1,1,1,1,1,4,4,2}; 135 | int tempo = 113; 136 | int pressbutton=1; 137 | //********************tone function********************************* 138 | int frequency(char note) 139 | { 140 | // This function takes a note character (a-g), and returns the 141 | // corresponding frequency in Hz for the tone() function. 142 | 143 | int i; 144 | const int numNotes = 8; // number of notes we're storing 145 | 146 | // The following arrays hold the note characters and their 147 | // corresponding frequencies. The last "C" note is uppercase 148 | // to separate it from the first lowercase "c". If you want to 149 | // add more notes, you'll need to use unique characters. 150 | 151 | // For the "char" (character) type, we put single characters 152 | // in single quotes. 153 | 154 | char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' }; 155 | int frequencies[] = {262, 294, 330, 349, 392, 440, 494, 523}; 156 | 157 | // Now we'll search through the letters in the array, and if 158 | // we find it, we'll return the frequency for that note. 159 | 160 | for (i = 0; i < numNotes; i++) // Step through the notes 161 | { 162 | if (names[i] == note) // Is this the one? 163 | { 164 | return(frequencies[i]); // Yes! Return the frequency 165 | } 166 | } 167 | return(0); // We looked through everything and didn't find it, 168 | // but we still need to return a value, so return 0. 169 | } 170 | 171 | //*******************clock function******************************** 172 | float pmangle=0,phangle=0,psangle=0; 173 | void drawClock(int hour,int minute, int second, int date, int month,int year,String week) 174 | { 175 | tft.setTextColor(ST7735_WHITE,ST7735_BLACK); 176 | //print digital clock 177 | tft.setCursor(tft.width()/2-40,tft.height()/2+20); 178 | tft.print(((hour%12)/10?(String)(hour%12):(" "+(String)(hour%12))));tft.print(":");tft.print((String)minute);tft.print(":");tft.print((second/10?(String)second:(" "+(String)second)));tft.print(" ");tft.print(hour/12?"PM":"AM"); 179 | 180 | mangle=-6*minute*3.14/180+3.14; 181 | hangle=-(30*hour+0.5*minute)*3.14/180+3.14; 182 | sangle=-6*second*3.14/180+3.14; 183 | //erase previous hands 184 | tft.drawLine(tft.width()/2,tft.height()/2,tft.width()/2+50*sin(pmangle),tft.height()/2+50*cos(pmangle),ST7735_BLACK); 185 | tft.drawLine(tft.width()/2,tft.height()/2,tft.width()/2+30*sin(phangle),tft.height()/2+35*cos(phangle),ST7735_BLACK); 186 | tft.drawLine(tft.width()/2,tft.height()/2,tft.width()/2+55*sin(psangle),tft.height()/2+55*cos(psangle),ST7735_BLACK); 187 | 188 | pmangle=mangle; 189 | phangle=hangle; 190 | psangle=sangle; 191 | //draw new hands 192 | tft.drawLine(tft.width()/2,tft.height()/2,tft.width()/2+50*sin(mangle),tft.height()/2+50*cos(mangle),ST7735_MAGENTA); 193 | tft.drawLine(tft.width()/2,tft.height()/2,tft.width()/2+30*sin(hangle),tft.height()/2+35*cos(hangle),ST7735_GREEN); 194 | tft.drawLine(tft.width()/2,tft.height()/2,tft.width()/2+55*sin(sangle),tft.height()/2+55*cos(sangle),ST7735_RED); 195 | 196 | //print date and day 197 | tft.setTextColor(ST7735_CYAN); 198 | tft.setTextSize(1); 199 | tft.setCursor(140,15); 200 | tft.print(week); 201 | tft.setCursor(115,5); 202 | tft.print(date);tft.print("-");tft.print(month);tft.print("-");tft.print(year); 203 | } 204 | //*******************clock function end************************* 205 | long t=millis(); 206 | 207 | void loop() 208 | { readPCF8563(); 209 | //send calender variables on serial port 210 | Serial.print(days[dayOfWeek]); 211 | Serial.print(" "); 212 | Serial.print(dayOfMonth, DEC); 213 | Serial.print("/"); 214 | Serial.print(month, DEC); 215 | Serial.print("/20"); 216 | Serial.print(year, DEC); 217 | Serial.print(" - "); 218 | Serial.print(hour, DEC); 219 | Serial.print(":"); 220 | if (minute < 10) 221 | { 222 | Serial.print("0"); 223 | } 224 | Serial.print(minute, DEC); 225 | Serial.print(":"); 226 | if (second < 10) 227 | { 228 | Serial.print("0"); 229 | } 230 | Serial.println(second, DEC); 231 | //draw alarm hand 232 | aangle=-((1-analogRead(alarmHand)/1023.0)*6.28); 233 | tft.drawLine(tft.width()/2,tft.height()/2,tft.width()/2+30*sin(paangle),tft.height()/2+28*cos(paangle),ST7735_BLACK); 234 | tft.drawLine(tft.width()/2,tft.height()/2,tft.width()/2+30*sin(aangle),tft.height()/2+28*cos(aangle),ST7735_YELLOW); 235 | drawClock(hour,minute,second,dayOfMonth,month,year,days[dayOfWeek]); 236 | paangle=aangle; 237 | delay(1000); 238 | //***********************alarm tone**************************************************** 239 | //subtract 2*pi from hour hand angle after 12 hours 240 | if(hangle<(-6.28)) 241 | hangle=hangle+6.28; 242 | Serial.println(digitalRead(alarmOnOff)); 243 | 244 | //draw bell icon if alarm is on 245 | if (digitalRead(alarmOnOff) == 1) tft.drawBitmap(140,108,bell,16,16,ST7735_YELLOW); 246 | else tft.drawBitmap(140,108,bell,16,16,ST7735_BLACK); 247 | 248 | //play tone 249 | if(abs(hangle-aangle)<=0.05&&digitalRead(alarmOnOff)==1) //do the alarm and hour hands match? and is the alarm on? 250 | { 251 | int i, duration; 252 | tone(buzzerPin,1000,1000); 253 | for (i = 0; i < songLength; i++) // step through the song arrays 254 | { 255 | duration = beats[i] * tempo; // length of note/rest in ms 256 | if (notes[i] == ' ') // is this a rest? 257 | { 258 | delay(duration); // then pause for a moment 259 | } 260 | else // otherwise, play the note 261 | { 262 | tone(buzzerPin, frequency(notes[i]), duration); 263 | delay(duration); // wait for tone to finish 264 | } 265 | delay(tempo/10); // brief pause between notes 266 | } 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /alarmClock/testPCF8563/testPCF8563.ino: -------------------------------------------------------------------------------- 1 | // Example 54.1 - PCF8563 RTC write/read demonstration 2 | 3 | #include "Wire.h" 4 | #define PCF8563address 0x51 5 | 6 | byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 7 | String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; 8 | 9 | byte bcdToDec(byte value) 10 | { 11 | return ((value / 16) * 10 + value % 16); 12 | } 13 | 14 | byte decToBcd(byte value){ 15 | return (value / 10 * 16 + value % 10); 16 | } 17 | 18 | void setPCF8563() 19 | // this sets the time and date to the PCF8563 20 | { 21 | Wire.beginTransmission(PCF8563address); 22 | Wire.write(0x02); 23 | Wire.write(decToBcd(second)); //second 24 | Wire.write(decToBcd(minute)); //minute 25 | Wire.write(decToBcd(hour)); //hour 26 | Wire.write(decToBcd(dayOfMonth)); //date 27 | Wire.write(decToBcd(dayOfWeek)); //day of week see_the_above array 28 | Wire.write(decToBcd(month)); //month 29 | Wire.write(decToBcd(year)); //year 30 | Wire.endTransmission(); 31 | } 32 | 33 | void readPCF8563() 34 | // this gets the time and date from the PCF8563 35 | { 36 | Wire.beginTransmission(PCF8563address); 37 | Wire.write(0x02); 38 | Wire.endTransmission(); 39 | Wire.requestFrom(PCF8563address, 7); 40 | second = bcdToDec(Wire.read() & B01111111); // remove VL error bit 41 | minute = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB 42 | hour = bcdToDec(Wire.read() & B00111111); 43 | dayOfMonth = bcdToDec(Wire.read() & B00111111); 44 | dayOfWeek = bcdToDec(Wire.read() & B00000111); 45 | month = bcdToDec(Wire.read() & B00011111); // remove century bit, 1999 is over 46 | year = bcdToDec(Wire.read()); 47 | } 48 | 49 | void setup() 50 | { 51 | Wire.begin(); 52 | Serial.begin(9600); 53 | // change the following to set your initial time 54 | second = 0; 55 | minute = 40; 56 | hour = 21; 57 | dayOfWeek = 0; 58 | dayOfMonth = 29; 59 | month = 5; 60 | year = 16; 61 | // comment out the next line and upload again to set and keep the time from resetting every reset 62 | setPCF8563(); 63 | } 64 | 65 | void loop() 66 | { 67 | readPCF8563(); 68 | Serial.print(days[dayOfWeek]); 69 | Serial.print(" "); 70 | Serial.print(dayOfMonth, DEC); 71 | Serial.print("/"); 72 | Serial.print(month, DEC); 73 | Serial.print("/20"); 74 | Serial.print(year, DEC); 75 | Serial.print(" - "); 76 | Serial.print(hour, DEC); 77 | Serial.print(":"); 78 | if (minute < 10) 79 | { 80 | Serial.print("0"); 81 | } 82 | Serial.print(minute, DEC); 83 | Serial.print(":"); 84 | if (second < 10) 85 | { 86 | Serial.print("0"); 87 | } 88 | Serial.println(second, DEC); 89 | delay(1000); 90 | } 91 | -------------------------------------------------------------------------------- /chattingUsingEvive/chattingUsingEvive/chattingUsingEvive.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * evive programming 3 | * 4 | */ 5 | void setup() 6 | { 7 | Serial.begin(9600); 8 | Serial3.begin(115200); 9 | Serial2.begin(14400); 10 | Serial3.println("AT+RST"); 11 | delay(100); 12 | Serial3.println("AT+CWMODE=2"); 13 | 14 | } 15 | int chating=0,f=0,c=0; 16 | int ipd=0,cal=0; 17 | void loop() 18 | { 19 | 20 | 21 | if (Serial3.available()){ 22 | while (Serial3.available()&&f==0&&chating==0) { 23 | Serial.write((char)Serial3.read()); 24 | } 25 | 26 | if(chating==1&&Serial3.available()) 27 | { 28 | int i; 29 | while(ipd==0&&Serial3.available()){ 30 | while(Serial3.available()) 31 | { 32 | Serial2.write(c); 33 | char c=(char)Serial3.read(); 34 | if(c==':') 35 | { long t=millis(); 36 | 37 | ipd=1; 38 | while(!Serial3.available()) 39 | { 40 | if(millis()>t+900) 41 | { ipd=0; 42 | break; 43 | } 44 | } 45 | break; 46 | } 47 | } 48 | 49 | } 50 | 51 | while(ipd==1&&Serial3.available()){ 52 | if(cal==0) 53 | { Serial.print("other-->"); 54 | cal=1; 55 | 56 | } 57 | if(!Serial.available()) 58 | { 59 | delay(10); 60 | if(!Serial.available()) 61 | ipd=0; 62 | } 63 | while(Serial3.available()) 64 | Serial.write(Serial3.read()); 65 | Serial.println(""); 66 | 67 | 68 | } 69 | 70 | 71 | } 72 | 73 | if(f>0) 74 | { 75 | //Serial3.println("you-->"); 76 | while (Serial3.available()) { 77 | Serial2.write(Serial3.read()); 78 | } 79 | f--; 80 | } 81 | 82 | cal=0; 83 | } 84 | if (Serial.available()){ 85 | delay(1000); 86 | cal=0; 87 | 88 | String command=""; 89 | while (Serial.available()) { 90 | command+=(char)Serial.read(); 91 | } 92 | 93 | if(chating==1) 94 | { 95 | Serial3.print("AT+CIPSEND=0,"); 96 | Serial3.println(command.length()+10); 97 | //Serial3.println('\r'); 98 | delay(500); 99 | Serial3.print("*OTHER*-->"); // 5 TAB SPACE 100 | Serial3.println(command); 101 | Serial3.write(10); 102 | Serial.print("*you*-->"); 103 | Serial.println(command); 104 | f=40; 105 | } 106 | else 107 | Serial3.println(command); 108 | 109 | if(command=="AT+CIPSERVER=1,1338") //START GHE CHATTING THIS MAKE NO NEED OF WRITING CIPSEND CMD 110 | { chating=1; 111 | Serial3.println(command); 112 | Serial.println("started"); 113 | } 114 | 115 | 116 | } 117 | 118 | } 119 | 120 | -------------------------------------------------------------------------------- /chattingUsingEvive/testESPv2/testESPv2.ino: -------------------------------------------------------------------------------- 1 | void setup() { 2 | Serial.begin(9600); 3 | Serial3.begin(115200); 4 | } 5 | 6 | void loop() { 7 | // put your main code here, to run repeatedly: 8 | if (Serial3.available()){ 9 | while (Serial3.available()){ 10 | char c=Serial3.read(); 11 | Serial.write(c); 12 | } 13 | } 14 | if (Serial.available()){ 15 | delay(1000); 16 | String command=""; 17 | while (Serial.available()){ 18 | command+=(char)Serial.read(); 19 | } 20 | Serial3.println(command); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/images/battery.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/imageToFlashMemoryIconsForTFT/images/battery.bmp -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/images/bell.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/imageToFlashMemoryIconsForTFT/images/bell.bmp -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/images/evive_in_hand.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/imageToFlashMemoryIconsForTFT/images/evive_in_hand.jpg -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/images/evive_logo.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/imageToFlashMemoryIconsForTFT/images/evive_logo.bmp -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/images/semiCircle.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/imageToFlashMemoryIconsForTFT/images/semiCircle.bmp -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/images/user.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/imageToFlashMemoryIconsForTFT/images/user.bmp -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/images/wifi.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/imageToFlashMemoryIconsForTFT/images/wifi.bmp -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/tftIcons/bitmaps.h: -------------------------------------------------------------------------------- 1 | #ifndef BITMAPS_H 2 | #define BITMAPS_H 3 | 4 | //Bell icon size: 16W*16H 5 | const unsigned char bell [] PROGMEM = { 6 | 0x01, 0x80, 0x03, 0xc0, 0x0f, 0xf0, 0x1f, 0xf8, 0x1f, 0xf8, 0x1f, 0xf8, 0x3f, 0xfc, 0x3f, 0xfc, 7 | 0x3f, 0xfc, 0x3f, 0xfc, 0x3f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfe, 0xc3, 0xc3, 0xc3, 0xc3, 0x3f, 0xfc, 8 | }; 9 | 10 | //SemiCircle size: 50W*25H 11 | const unsigned char semiCircle [] PROGMEM = { 12 | 0x00, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 13 | 0x00, 0x00, 0x7f, 0xff, 0x80, 0x00, 0x00, 14 | 0x00, 0x03, 0xff, 0xff, 0xf0, 0x00, 0x00, 15 | 0x00, 0x0f, 0xf0, 0x03, 0xfc, 0x00, 0x00, 16 | 0x00, 0x1f, 0x80, 0x00, 0x7e, 0x00, 0x00, 17 | 0x00, 0x7e, 0x00, 0x00, 0x1f, 0x80, 0x00, 18 | 0x00, 0xf8, 0x00, 0x00, 0x07, 0xc0, 0x00, 19 | 0x01, 0xf0, 0x00, 0x00, 0x03, 0xe0, 0x00, 20 | 0x03, 0xc0, 0x00, 0x00, 0x00, 0xf0, 0x00, 21 | 0x07, 0x80, 0x00, 0x00, 0x00, 0x78, 0x00, 22 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 23 | 0x0f, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 24 | 0x1e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 25 | 0x1c, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 26 | 0x3c, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 27 | 0x38, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 28 | 0x38, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 29 | 0x70, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 30 | 0x70, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 31 | 0x70, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 32 | 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 33 | 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 34 | 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 35 | 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0, 36 | 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc0 37 | }; 38 | 39 | //wifi icon size: 20W*15H px 40 | const unsigned char wifi_icon [] PROGMEM = { 41 | 0x01, 0x68, 0x00, 42 | 0x07, 0xfe, 0x00, 43 | 0x1f, 0xff, 0x80, 44 | 0x7f, 0x0f, 0xe0, 45 | 0x78, 0x01, 0xe0, 46 | 0x70, 0x00, 0xe0, 47 | 0x00, 0xf0, 0x00, 48 | 0x03, 0xfc, 0x00, 49 | 0x07, 0xfe, 0x00, 50 | 0x07, 0x0e, 0x00, 51 | 0x02, 0x00, 0x00, 52 | 0x00, 0x00, 0x00, 53 | 0x00, 0x60, 0x00, 54 | 0x00, 0x70, 0x00, 55 | 0x00, 0x60, 0x00 56 | }; 57 | 58 | //battery icon size: 20W*15H px 59 | const unsigned char battery_icon [] PROGMEM = { 60 | 0x00, 0x00, 0x00, 61 | 0x00, 0x00, 0x00, 62 | 0x00, 0x00, 0x00, 63 | 0xff, 0xff, 0x80, 64 | 0xff, 0xc1, 0x80, 65 | 0xff, 0xc1, 0xe0, 66 | 0xff, 0xc1, 0xe0, 67 | 0xff, 0xc1, 0xe0, 68 | 0xff, 0xc1, 0xe0, 69 | 0xff, 0xc1, 0xe0, 70 | 0xff, 0xc1, 0x80, 71 | 0xff, 0xff, 0x80, 72 | 0x00, 0x00, 0x00, 73 | 0x00, 0x00, 0x00, 74 | 0x00, 0x00, 0x00 75 | }; 76 | 77 | //user_icon Size: 15W*15H px 78 | const unsigned char user_icon [] PROGMEM = { 79 | 0x03, 0x80, 80 | 0x0f, 0xe0, 81 | 0x0f, 0xe0, 82 | 0x1f, 0xf0, 83 | 0x1f, 0xf0, 84 | 0x1f, 0xf0, 85 | 0x0f, 0xe0, 86 | 0x0f, 0xe0, 87 | 0x03, 0x80, 88 | 0x38, 0x38, 89 | 0x7f, 0xfc, 90 | 0x7f, 0xfc, 91 | 0xff, 0xfe, 92 | 0xff, 0xfe, 93 | 0xff, 0xfe 94 | }; 95 | 96 | //evive_logo Size: 71W*71H px 97 | const unsigned char evive_logo [] PROGMEM = { 98 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 99 | 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 100 | 0x00, 0x00, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x00, 0x00, 101 | 0x00, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 102 | 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 103 | 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 104 | 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 105 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 106 | 0x00, 0x03, 0xff, 0xfc, 0x00, 0x7f, 0xff, 0x00, 0x00, 107 | 0x00, 0x07, 0xff, 0xc0, 0x00, 0x07, 0xff, 0xc0, 0x00, 108 | 0x00, 0x0f, 0xff, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 109 | 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 110 | 0x00, 0x07, 0xf8, 0x07, 0xff, 0x80, 0x3f, 0xc0, 0x00, 111 | 0x00, 0x03, 0xf8, 0x1f, 0xff, 0xf0, 0x0f, 0x80, 0x00, 112 | 0x00, 0x01, 0xfc, 0x7f, 0xff, 0xfc, 0x07, 0x00, 0x00, 113 | 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 114 | 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 115 | 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x7f, 0xc0, 0x00, 0x00, 116 | 0x00, 0x00, 0x1f, 0xe0, 0x00, 0x1f, 0xe0, 0x00, 0x00, 117 | 0x02, 0x00, 0x0f, 0xc0, 0x00, 0x07, 0xe0, 0x00, 0x80, 118 | 0x07, 0x80, 0x07, 0xc0, 0x00, 0x01, 0xc0, 0x03, 0xc0, 119 | 0x0f, 0xc0, 0x03, 0xe3, 0xff, 0x80, 0x00, 0x0f, 0xe0, 120 | 0x0f, 0xf0, 0x01, 0xff, 0xff, 0xe0, 0x00, 0x1f, 0xe0, 121 | 0x1f, 0xfc, 0x00, 0xff, 0xff, 0xf0, 0x00, 0x7f, 0xe0, 122 | 0x1f, 0xff, 0x00, 0x7f, 0xff, 0xf8, 0x01, 0xff, 0xf0, 123 | 0x1f, 0xff, 0x80, 0x3f, 0x83, 0xf8, 0x07, 0xff, 0xe0, 124 | 0x07, 0xff, 0xe0, 0x1e, 0x00, 0xf0, 0x0f, 0xff, 0xc0, 125 | 0x03, 0xff, 0xf8, 0x08, 0x00, 0x00, 0x3f, 0xff, 0x00, 126 | 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 127 | 0x00, 0x3f, 0xff, 0x00, 0x00, 0x01, 0xff, 0xf8, 0x00, 128 | 0x00, 0x0f, 0xff, 0xc0, 0xfe, 0x07, 0xff, 0xe0, 0x00, 129 | 0x00, 0x07, 0xff, 0xc1, 0xff, 0x07, 0xff, 0x80, 0x00, 130 | 0x00, 0x01, 0xff, 0xc3, 0xff, 0x87, 0xff, 0x00, 0x00, 131 | 0x00, 0x00, 0x7f, 0x83, 0xff, 0x87, 0xfc, 0x00, 0x00, 132 | 0x00, 0x00, 0x3f, 0x83, 0xff, 0x83, 0xf8, 0x00, 0x00, 133 | 0x00, 0x00, 0x3f, 0x83, 0xff, 0x83, 0xf8, 0x00, 0x00, 134 | 0x00, 0x00, 0x3f, 0x83, 0xff, 0x83, 0xf8, 0x00, 0x00, 135 | 0x00, 0x00, 0x7f, 0x83, 0xff, 0x87, 0xfc, 0x00, 0x00, 136 | 0x00, 0x01, 0xff, 0xc3, 0xff, 0x87, 0xfe, 0x00, 0x00, 137 | 0x00, 0x03, 0xff, 0xc1, 0xff, 0x07, 0xff, 0x80, 0x00, 138 | 0x00, 0x0f, 0xff, 0xc0, 0xfe, 0x07, 0xff, 0xe0, 0x00, 139 | 0x00, 0x3f, 0xff, 0x00, 0x00, 0x03, 0xff, 0xf8, 0x00, 140 | 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 141 | 0x01, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x3f, 0xff, 0x00, 142 | 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xc0, 143 | 0x1f, 0xff, 0xc0, 0x03, 0x83, 0x80, 0x07, 0xff, 0xe0, 144 | 0x1f, 0xff, 0x00, 0x07, 0xff, 0xc0, 0x01, 0xff, 0xf0, 145 | 0x1f, 0xfc, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x7f, 0xf0, 146 | 0x0f, 0xf0, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x1f, 0xe0, 147 | 0x0f, 0xe0, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x0f, 0xe0, 148 | 0x07, 0x80, 0x00, 0x1f, 0xff, 0xf0, 0x00, 0x03, 0xc0, 149 | 0x06, 0x00, 0x00, 0x3f, 0xff, 0xf0, 0x00, 0x00, 0x80, 150 | 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x00, 151 | 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 152 | 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfc, 0x00, 0x00, 0x00, 153 | 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 154 | 0x00, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 155 | 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 156 | 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 157 | 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 158 | 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 159 | 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 160 | 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 161 | 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 162 | 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 163 | 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 164 | 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 165 | 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 166 | 0x00, 0x00, 0x00, 0x3f, 0xff, 0xf8, 0x00, 0x00, 0x00, 167 | 0x00, 0x00, 0x00, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x00, 168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 169 | }; 170 | #endif 171 | -------------------------------------------------------------------------------- /imageToFlashMemoryIconsForTFT/tftIcons/tftIcons.ino: -------------------------------------------------------------------------------- 1 | //Checked with evive / Arduino Mega 2 | //Compatible with SPI based TFT (user can modify TFT codes and library) 3 | //Date: 20160623 4 | //Developer: Dhrupal R Shah 5 | 6 | #include // Core graphics library 7 | #include // Hardware-specific library 8 | 9 | #include "bitmaps.h" 10 | #include "bitmapsLarge.h" 11 | 12 | // For the breakout, you can use any 2 or 3 pins 13 | // These pins will also work for the 1.8" TFT shield 14 | #define TFT_CS 48 15 | #define TFT_RST 47 // you can also connect this to the Arduino reset 16 | // in which case, set this #define pin to 0! 17 | #define TFT_DC 49 18 | 19 | Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 20 | 21 | void setup() { 22 | tft.initR(INITR_BLACKTAB); 23 | tft.setRotation(1); 24 | tft.fillScreen(ST7735_BLACK); 25 | 26 | //Case 1: Monochrome Bitmaps 27 | // tft.drawBitmap(0,0,bell,16,16,ST7735_WHITE); 28 | // tft.drawBitmap(0,0,semiCircle, 50, 25, ST7735_WHITE); 29 | // tft.drawBitmap(0,0,myBitmap, 71, 71, ST7735_CYAN); 30 | // tft.drawBitmap(10,0,wifi_icon, 20, 15, ST7735_WHITE); 31 | // tft.drawBitmap(130,0,battery_icon, 20, 15, ST7735_WHITE); 32 | // tft.drawBitmap(70,0,user_icon, 15, 15, ST7735_WHITE); 33 | // tft.drawBitmap(0,0,evive_logo, 71, 71, ST7735_CYAN); 34 | 35 | 36 | //Case 2: Multi Colored Images/Icons 37 | int h = 128,w = 97, row, col, buffidx=0; 38 | for (row=0; row 11 | 12 | unsigned long white = 0xFFFFFF; 13 | 14 | //Pin mapping for dual channel motor driver in evive 15 | int motor1PWM = 44; 16 | int motor1DIR1 = 28; 17 | int motor1DIR2 = 29; 18 | int motor2PWM = 45; 19 | int motor2DIR1 = 30; 20 | int motor2DIR2 = 31; 21 | int flag = 0; 22 | 23 | void setup() { 24 | OneSheeld.begin(); 25 | ColorDetector.setOnSelected(&selected); 26 | pinMode(motor1PWM, OUTPUT); 27 | pinMode(motor1DIR1, OUTPUT); 28 | pinMode(motor1DIR2, OUTPUT); 29 | pinMode(motor2PWM, OUTPUT); 30 | pinMode(motor2DIR1, OUTPUT); 31 | pinMode(motor2DIR2, OUTPUT); 32 | 33 | digitalWrite(motor1DIR2, LOW); 34 | digitalWrite(motor1DIR1, HIGH); 35 | digitalWrite(motor2DIR2, LOW); 36 | digitalWrite(motor2DIR1, HIGH); 37 | } 38 | 39 | void loop() { 40 | } 41 | 42 | void selected() 43 | { 44 | ColorDetector.setPalette(_3_BIT_RGB_PALETTE); 45 | ColorDetector.enableFullOperation(); 46 | ColorDetector.setCalculationMode(MOST_DOMINANT_COLOR); 47 | ColorDetector.setOnNewColor(&newColor); 48 | } 49 | 50 | void newColor(Color one,Color two,Color three,Color four,Color five,Color six,Color seven,Color eight,Color nine) 51 | { 52 | 53 | if (three == white && one == white) 54 | { moveForward(); 55 | //The following conditions helps in remembering history for undershoot case of line following, 56 | //i.e. robot was not able to turn towards line and escapes line 57 | //if below code is uncommented, then comment out the "moveForward()" command above 58 | // if(flag == -1) moveLeft(); 59 | // else if (flag == 1) moveRight(); 60 | // else if ( two !=white){ 61 | // moveForward(); 62 | // flag = 0; 63 | } 64 | } 65 | else if (three == white && one != white) 66 | { moveLeft(); 67 | flag = -1; 68 | } 69 | else if (one == white && three != white) 70 | { moveRight(); 71 | flag = 1; 72 | } 73 | } 74 | 75 | void moveForward() 76 | { 77 | analogWrite(motor1PWM, 200); 78 | analogWrite(motor2PWM, 200); 79 | } 80 | 81 | void moveRight() 82 | { 83 | analogWrite(motor1PWM, 250); 84 | analogWrite(motor2PWM, 100); 85 | } 86 | 87 | void moveLeft() 88 | { 89 | analogWrite(motor1PWM, 100); 90 | analogWrite(motor2PWM, 250); 91 | } 92 | -------------------------------------------------------------------------------- /mobileMicroscope/STL files/Bottom.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/mobileMicroscope/STL files/Bottom.stl -------------------------------------------------------------------------------- /mobileMicroscope/STL files/FocussingScrews.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/mobileMicroscope/STL files/FocussingScrews.stl -------------------------------------------------------------------------------- /mobileMicroscope/STL files/SlideHolder.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/mobileMicroscope/STL files/SlideHolder.stl -------------------------------------------------------------------------------- /mobileMicroscope/STL files/Top.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STEMpedia/eviveProjects/332f0ffe960b69379c56d2551786473e67362b3b/mobileMicroscope/STL files/Top.stl -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/README.adoc: -------------------------------------------------------------------------------- 1 | = Servo Library for Arduino = 2 | 3 | This library allows an Arduino board to control RC (hobby) servo motors. 4 | 5 | For more information about this library please visit us at 6 | http://www.arduino.cc/en/Reference/Servo 7 | 8 | == License == 9 | 10 | Copyright (c) 2013 Arduino LLC. All right reserved. 11 | Copyright (c) 2009 Michael Margolis. All right reserved. 12 | 13 | This library is free software; you can redistribute it and/or 14 | modify it under the terms of the GNU Lesser General Public 15 | License as published by the Free Software Foundation; either 16 | version 2.1 of the License, or (at your option) any later version. 17 | 18 | This library is distributed in the hope that it will be useful, 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | Lesser General Public License for more details. 22 | 23 | You should have received a copy of the GNU Lesser General Public 24 | License along with this library; if not, write to the Free Software 25 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/examples/Knob/Knob.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Controlling a servo position using a potentiometer (variable resistor) 3 | by Michal Rinott 4 | 5 | modified on 8 Nov 2013 6 | by Scott Fitzgerald 7 | http://www.arduino.cc/en/Tutorial/Knob 8 | */ 9 | 10 | #include 11 | 12 | Servo myservo; // create servo object to control a servo 13 | 14 | int potpin = 0; // analog pin used to connect the potentiometer 15 | int val; // variable to read the value from the analog pin 16 | 17 | void setup() { 18 | myservo.attach(9); // attaches the servo on pin 9 to the servo object 19 | } 20 | 21 | void loop() { 22 | val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023) 23 | val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180) 24 | myservo.write(val); // sets the servo position according to the scaled value 25 | delay(15); // waits for the servo to get there 26 | } 27 | 28 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/examples/Sweep/Sweep.ino: -------------------------------------------------------------------------------- 1 | /* Sweep 2 | by BARRAGAN 3 | This example code is in the public domain. 4 | 5 | modified 8 Nov 2013 6 | by Scott Fitzgerald 7 | http://www.arduino.cc/en/Tutorial/Sweep 8 | */ 9 | 10 | #include 11 | 12 | Servo myservo; // create servo object to control a servo 13 | // twelve servo objects can be created on most boards 14 | 15 | int pos = 0; // variable to store the servo position 16 | 17 | void setup() { 18 | myservo.attach(9); // attaches the servo on pin 9 to the servo object 19 | } 20 | 21 | void loop() { 22 | for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees 23 | // in steps of 1 degree 24 | myservo.write(pos); // tell servo to go to position in variable 'pos' 25 | delay(15); // waits 15ms for the servo to reach the position 26 | } 27 | for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees 28 | myservo.write(pos); // tell servo to go to position in variable 'pos' 29 | delay(15); // waits 15ms for the servo to reach the position 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map Servo 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Servo KEYWORD1 Servo 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | attach KEYWORD2 15 | detach KEYWORD2 16 | write KEYWORD2 17 | read KEYWORD2 18 | attached KEYWORD2 19 | writeMicroseconds KEYWORD2 20 | readMicroseconds KEYWORD2 21 | 22 | ####################################### 23 | # Constants (LITERAL1) 24 | ####################################### 25 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/library.properties: -------------------------------------------------------------------------------- 1 | name=Servo 2 | version=1.1.2 3 | author=Michael Margolis, Arduino 4 | maintainer=Arduino 5 | sentence=Allows Arduino/Genuino boards to control a variety of servo motors. 6 | paragraph=This library can control a great number of servos.
It makes careful use of timers: the library can control 12 servos using only 1 timer.
On the Arduino Due you can control up to 60 servos.
7 | category=Device Control 8 | url=http://www.arduino.cc/en/Reference/Servo 9 | architectures=avr,sam,samd 10 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/src/Servo.h: -------------------------------------------------------------------------------- 1 | /* 2 | Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 3 | Copyright (c) 2009 Michael Margolis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | /* 21 | A servo is activated by creating an instance of the Servo class passing 22 | the desired pin to the attach() method. 23 | The servos are pulsed in the background using the value most recently 24 | written using the write() method. 25 | 26 | Note that analogWrite of PWM on pins associated with the timer are 27 | disabled when the first servo is attached. 28 | Timers are seized as needed in groups of 12 servos - 24 servos use two 29 | timers, 48 servos will use four. 30 | The sequence used to sieze timers is defined in timers.h 31 | 32 | The methods are: 33 | 34 | Servo - Class for manipulating servo motors connected to Arduino pins. 35 | 36 | attach(pin ) - Attaches a servo motor to an i/o pin. 37 | attach(pin, min, max ) - Attaches to a pin setting min and max values in microseconds 38 | default min is 544, max is 2400 39 | 40 | write() - Sets the servo angle in degrees. (invalid angle that is valid as pulse in microseconds is treated as microseconds) 41 | writeMicroseconds() - Sets the servo pulse width in microseconds 42 | read() - Gets the last written servo pulse width as an angle between 0 and 180. 43 | readMicroseconds() - Gets the last written servo pulse width in microseconds. (was read_us() in first release) 44 | attached() - Returns true if there is a servo attached. 45 | detach() - Stops an attached servos from pulsing its i/o pin. 46 | */ 47 | 48 | #ifndef Servo_h 49 | #define Servo_h 50 | 51 | #include 52 | 53 | /* 54 | * Defines for 16 bit timers used with Servo library 55 | * 56 | * If _useTimerX is defined then TimerX is a 16 bit timer on the current board 57 | * timer16_Sequence_t enumerates the sequence that the timers should be allocated 58 | * _Nbr_16timers indicates how many 16 bit timers are available. 59 | */ 60 | 61 | // Architecture specific include 62 | #if defined(ARDUINO_ARCH_AVR) 63 | #include "avr/ServoTimers.h" 64 | #elif defined(ARDUINO_ARCH_SAM) 65 | #include "sam/ServoTimers.h" 66 | #elif defined(ARDUINO_ARCH_SAMD) 67 | #include "samd/ServoTimers.h" 68 | #else 69 | #error "This library only supports boards with an AVR, SAM or SAMD processor." 70 | #endif 71 | 72 | #define Servo_VERSION 2 // software version of this library 73 | 74 | #define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo 75 | #define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo 76 | #define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached 77 | #define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds 78 | 79 | #define SERVOS_PER_TIMER 12 // the maximum number of servos controlled by one timer 80 | #define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER) 81 | 82 | #define INVALID_SERVO 255 // flag indicating an invalid servo index 83 | 84 | typedef struct { 85 | uint8_t nbr :6 ; // a pin number from 0 to 63 86 | uint8_t isActive :1 ; // true if this channel is enabled, pin not pulsed if false 87 | } ServoPin_t ; 88 | 89 | typedef struct { 90 | ServoPin_t Pin; 91 | volatile unsigned int ticks; 92 | } servo_t; 93 | 94 | class Servo 95 | { 96 | public: 97 | Servo(); 98 | uint8_t attach(int pin); // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure 99 | uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. 100 | void detach(); 101 | void write(int value); // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds 102 | void writeMicroseconds(int value); // Write pulse width in microseconds 103 | int read(); // returns current pulse width as an angle between 0 and 180 degrees 104 | int readMicroseconds(); // returns current pulse width in microseconds for this servo (was read_us() in first release) 105 | bool attached(); // return true if this servo is attached, otherwise false 106 | private: 107 | uint8_t servoIndex; // index into the channel data for this servo 108 | int8_t min; // minimum is this value times 4 added to MIN_PULSE_WIDTH 109 | int8_t max; // maximum is this value times 4 added to MAX_PULSE_WIDTH 110 | }; 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/src/avr/Servo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Servo.cpp - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 3 | Copyright (c) 2009 Michael Margolis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #if defined(ARDUINO_ARCH_AVR) 21 | 22 | #include 23 | #include 24 | 25 | #include "Servo.h" 26 | 27 | #define usToTicks(_us) (( clockCyclesPerMicrosecond()* _us) / 8) // converts microseconds to tick (assumes prescale of 8) // 12 Aug 2009 28 | #define ticksToUs(_ticks) (( (unsigned)_ticks * 8)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds 29 | 30 | 31 | #define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009 32 | 33 | //#define NBR_TIMERS (MAX_SERVOS / SERVOS_PER_TIMER) 34 | 35 | static servo_t servos[MAX_SERVOS]; // static array of servo structures 36 | static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) 37 | 38 | uint8_t ServoCount = 0; // the total number of attached servos 39 | 40 | 41 | // convenience macros 42 | #define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo 43 | #define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer 44 | #define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel 45 | #define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel 46 | 47 | #define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo 48 | #define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo 49 | 50 | /************ static functions common to all instances ***********************/ 51 | 52 | static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t *TCNTn, volatile uint16_t* OCRnA) 53 | { 54 | if( Channel[timer] < 0 ) 55 | *TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer 56 | else{ 57 | if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true ) 58 | digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,LOW); // pulse this channel low if activated 59 | } 60 | 61 | Channel[timer]++; // increment to the next channel 62 | if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { 63 | *OCRnA = *TCNTn + SERVO(timer,Channel[timer]).ticks; 64 | if(SERVO(timer,Channel[timer]).Pin.isActive == true) // check if activated 65 | digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high 66 | } 67 | else { 68 | // finished all channels so wait for the refresh period to expire before starting over 69 | if( ((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL) ) // allow a few ticks to ensure the next OCR1A not missed 70 | *OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL); 71 | else 72 | *OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed 73 | Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel 74 | } 75 | } 76 | 77 | #ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform 78 | // Interrupt handlers for Arduino 79 | #if defined(_useTimer1) 80 | SIGNAL (TIMER1_COMPA_vect) 81 | { 82 | handle_interrupts(_timer1, &TCNT1, &OCR1A); 83 | } 84 | #endif 85 | 86 | #if defined(_useTimer3) 87 | SIGNAL (TIMER3_COMPA_vect) 88 | { 89 | handle_interrupts(_timer3, &TCNT3, &OCR3A); 90 | } 91 | #endif 92 | 93 | #if defined(_useTimer4) 94 | SIGNAL (TIMER4_COMPA_vect) 95 | { 96 | handle_interrupts(_timer4, &TCNT4, &OCR4A); 97 | } 98 | #endif 99 | 100 | #if defined(_useTimer5) 101 | SIGNAL (TIMER5_COMPA_vect) 102 | { 103 | handle_interrupts(_timer5, &TCNT5, &OCR5A); 104 | } 105 | #endif 106 | 107 | #elif defined WIRING 108 | // Interrupt handlers for Wiring 109 | #if defined(_useTimer1) 110 | void Timer1Service() 111 | { 112 | handle_interrupts(_timer1, &TCNT1, &OCR1A); 113 | } 114 | #endif 115 | #if defined(_useTimer3) 116 | void Timer3Service() 117 | { 118 | handle_interrupts(_timer3, &TCNT3, &OCR3A); 119 | } 120 | #endif 121 | #endif 122 | 123 | 124 | static void initISR(timer16_Sequence_t timer) 125 | { 126 | #if defined (_useTimer1) 127 | if(timer == _timer1) { 128 | TCCR1A = 0; // normal counting mode 129 | TCCR1B = _BV(CS11); // set prescaler of 8 130 | TCNT1 = 0; // clear the timer count 131 | #if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__) 132 | TIFR |= _BV(OCF1A); // clear any pending interrupts; 133 | TIMSK |= _BV(OCIE1A) ; // enable the output compare interrupt 134 | #else 135 | // here if not ATmega8 or ATmega128 136 | TIFR1 |= _BV(OCF1A); // clear any pending interrupts; 137 | TIMSK1 |= _BV(OCIE1A) ; // enable the output compare interrupt 138 | #endif 139 | #if defined(WIRING) 140 | timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service); 141 | #endif 142 | } 143 | #endif 144 | 145 | #if defined (_useTimer3) 146 | if(timer == _timer3) { 147 | TCCR3A = 0; // normal counting mode 148 | TCCR3B = _BV(CS31); // set prescaler of 8 149 | TCNT3 = 0; // clear the timer count 150 | #if defined(__AVR_ATmega128__) 151 | TIFR |= _BV(OCF3A); // clear any pending interrupts; 152 | ETIMSK |= _BV(OCIE3A); // enable the output compare interrupt 153 | #else 154 | TIFR3 = _BV(OCF3A); // clear any pending interrupts; 155 | TIMSK3 = _BV(OCIE3A) ; // enable the output compare interrupt 156 | #endif 157 | #if defined(WIRING) 158 | timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only 159 | #endif 160 | } 161 | #endif 162 | 163 | #if defined (_useTimer4) 164 | if(timer == _timer4) { 165 | TCCR4A = 0; // normal counting mode 166 | TCCR4B = _BV(CS41); // set prescaler of 8 167 | TCNT4 = 0; // clear the timer count 168 | TIFR4 = _BV(OCF4A); // clear any pending interrupts; 169 | TIMSK4 = _BV(OCIE4A) ; // enable the output compare interrupt 170 | } 171 | #endif 172 | 173 | #if defined (_useTimer5) 174 | if(timer == _timer5) { 175 | TCCR5A = 0; // normal counting mode 176 | TCCR5B = _BV(CS51); // set prescaler of 8 177 | TCNT5 = 0; // clear the timer count 178 | TIFR5 = _BV(OCF5A); // clear any pending interrupts; 179 | TIMSK5 = _BV(OCIE5A) ; // enable the output compare interrupt 180 | } 181 | #endif 182 | } 183 | 184 | static void finISR(timer16_Sequence_t timer) 185 | { 186 | //disable use of the given timer 187 | #if defined WIRING // Wiring 188 | if(timer == _timer1) { 189 | #if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) 190 | TIMSK1 &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt 191 | #else 192 | TIMSK &= ~_BV(OCIE1A) ; // disable timer 1 output compare interrupt 193 | #endif 194 | timerDetach(TIMER1OUTCOMPAREA_INT); 195 | } 196 | else if(timer == _timer3) { 197 | #if defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__) 198 | TIMSK3 &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt 199 | #else 200 | ETIMSK &= ~_BV(OCIE3A); // disable the timer3 output compare A interrupt 201 | #endif 202 | timerDetach(TIMER3OUTCOMPAREA_INT); 203 | } 204 | #else 205 | //For arduino - in future: call here to a currently undefined function to reset the timer 206 | #endif 207 | } 208 | 209 | static boolean isTimerActive(timer16_Sequence_t timer) 210 | { 211 | // returns true if any servo is active on this timer 212 | for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { 213 | if(SERVO(timer,channel).Pin.isActive == true) 214 | return true; 215 | } 216 | return false; 217 | } 218 | 219 | 220 | /****************** end of static functions ******************************/ 221 | 222 | Servo::Servo() 223 | { 224 | if( ServoCount < MAX_SERVOS) { 225 | this->servoIndex = ServoCount++; // assign a servo index to this instance 226 | servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values - 12 Aug 2009 227 | } 228 | else 229 | this->servoIndex = INVALID_SERVO ; // too many servos 230 | } 231 | 232 | uint8_t Servo::attach(int pin) 233 | { 234 | return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); 235 | } 236 | 237 | uint8_t Servo::attach(int pin, int min, int max) 238 | { 239 | if(this->servoIndex < MAX_SERVOS ) { 240 | pinMode( pin, OUTPUT) ; // set servo pin to output 241 | servos[this->servoIndex].Pin.nbr = pin; 242 | // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 243 | this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS 244 | this->max = (MAX_PULSE_WIDTH - max)/4; 245 | // initialize the timer if it has not already been initialized 246 | timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); 247 | if(isTimerActive(timer) == false) 248 | initISR(timer); 249 | servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive 250 | } 251 | return this->servoIndex ; 252 | } 253 | 254 | void Servo::detach() 255 | { 256 | servos[this->servoIndex].Pin.isActive = false; 257 | timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex); 258 | if(isTimerActive(timer) == false) { 259 | finISR(timer); 260 | } 261 | } 262 | 263 | void Servo::write(int value) 264 | { 265 | if(value < MIN_PULSE_WIDTH) 266 | { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) 267 | if(value < 0) value = 0; 268 | if(value > 180) value = 180; 269 | value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); 270 | } 271 | this->writeMicroseconds(value); 272 | } 273 | 274 | void Servo::writeMicroseconds(int value) 275 | { 276 | // calculate and store the values for the given channel 277 | byte channel = this->servoIndex; 278 | if( (channel < MAX_SERVOS) ) // ensure channel is valid 279 | { 280 | if( value < SERVO_MIN() ) // ensure pulse width is valid 281 | value = SERVO_MIN(); 282 | else if( value > SERVO_MAX() ) 283 | value = SERVO_MAX(); 284 | 285 | value = value - TRIM_DURATION; 286 | value = usToTicks(value); // convert to ticks after compensating for interrupt overhead - 12 Aug 2009 287 | 288 | uint8_t oldSREG = SREG; 289 | cli(); 290 | servos[channel].ticks = value; 291 | SREG = oldSREG; 292 | } 293 | } 294 | 295 | int Servo::read() // return the value as degrees 296 | { 297 | return map( this->readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); 298 | } 299 | 300 | int Servo::readMicroseconds() 301 | { 302 | unsigned int pulsewidth; 303 | if( this->servoIndex != INVALID_SERVO ) 304 | pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION ; // 12 aug 2009 305 | else 306 | pulsewidth = 0; 307 | 308 | return pulsewidth; 309 | } 310 | 311 | bool Servo::attached() 312 | { 313 | return servos[this->servoIndex].Pin.isActive ; 314 | } 315 | 316 | #endif // ARDUINO_ARCH_AVR 317 | 318 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/src/avr/ServoTimers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2 3 | Copyright (c) 2009 Michael Margolis. All right reserved. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | 15 | You should have received a copy of the GNU Lesser General Public 16 | License along with this library; if not, write to the Free Software 17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | /* 21 | * Defines for 16 bit timers used with Servo library 22 | * 23 | * If _useTimerX is defined then TimerX is a 16 bit timer on the current board 24 | * timer16_Sequence_t enumerates the sequence that the timers should be allocated 25 | * _Nbr_16timers indicates how many 16 bit timers are available. 26 | */ 27 | 28 | /** 29 | * AVR Only definitions 30 | * -------------------- 31 | */ 32 | 33 | // Say which 16 bit timers can be used and in what order 34 | #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 35 | #define _useTimer5 36 | #define _useTimer1 37 | #define _useTimer3 38 | #define _useTimer4 39 | typedef enum { _timer1, _timer5, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t; 40 | 41 | #elif defined(__AVR_ATmega32U4__) 42 | #define _useTimer1 43 | typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; 44 | 45 | #elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) 46 | #define _useTimer3 47 | #define _useTimer1 48 | typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t; 49 | 50 | #elif defined(__AVR_ATmega128__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega2561__) 51 | #define _useTimer3 52 | #define _useTimer1 53 | typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t; 54 | 55 | #else // everything else 56 | #define _useTimer1 57 | typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t; 58 | #endif 59 | 60 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/src/sam/Servo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #if defined(ARDUINO_ARCH_SAM) 20 | 21 | #include 22 | #include 23 | 24 | #define usToTicks(_us) (( clockCyclesPerMicrosecond() * _us) / 32) // converts microseconds to tick 25 | #define ticksToUs(_ticks) (( (unsigned)_ticks * 32)/ clockCyclesPerMicrosecond() ) // converts from ticks back to microseconds 26 | 27 | #define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays 28 | 29 | static servo_t servos[MAX_SERVOS]; // static array of servo structures 30 | 31 | uint8_t ServoCount = 0; // the total number of attached servos 32 | 33 | static volatile int8_t Channel[_Nbr_16timers ]; // counter for the servo being pulsed for each timer (or -1 if refresh interval) 34 | 35 | // convenience macros 36 | #define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo 37 | #define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer 38 | #define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel 39 | #define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel 40 | 41 | #define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo 42 | #define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo 43 | 44 | /************ static functions common to all instances ***********************/ 45 | 46 | //------------------------------------------------------------------------------ 47 | /// Interrupt handler for the TC0 channel 1. 48 | //------------------------------------------------------------------------------ 49 | void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel); 50 | #if defined (_useTimer1) 51 | void HANDLER_FOR_TIMER1(void) { 52 | Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); 53 | } 54 | #endif 55 | #if defined (_useTimer2) 56 | void HANDLER_FOR_TIMER2(void) { 57 | Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); 58 | } 59 | #endif 60 | #if defined (_useTimer3) 61 | void HANDLER_FOR_TIMER3(void) { 62 | Servo_Handler(_timer3, TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); 63 | } 64 | #endif 65 | #if defined (_useTimer4) 66 | void HANDLER_FOR_TIMER4(void) { 67 | Servo_Handler(_timer4, TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); 68 | } 69 | #endif 70 | #if defined (_useTimer5) 71 | void HANDLER_FOR_TIMER5(void) { 72 | Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); 73 | } 74 | #endif 75 | 76 | void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel) 77 | { 78 | // clear interrupt 79 | tc->TC_CHANNEL[channel].TC_SR; 80 | if (Channel[timer] < 0) { 81 | tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer 82 | } else { 83 | if (SERVO_INDEX(timer,Channel[timer]) < ServoCount && SERVO(timer,Channel[timer]).Pin.isActive == true) { 84 | digitalWrite(SERVO(timer,Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated 85 | } 86 | } 87 | 88 | Channel[timer]++; // increment to the next channel 89 | if( SERVO_INDEX(timer,Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) { 90 | tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks; 91 | if(SERVO(timer,Channel[timer]).Pin.isActive == true) { // check if activated 92 | digitalWrite( SERVO(timer,Channel[timer]).Pin.nbr,HIGH); // its an active channel so pulse it high 93 | } 94 | } 95 | else { 96 | // finished all channels so wait for the refresh period to expire before starting over 97 | if( (tc->TC_CHANNEL[channel].TC_CV) + 4 < usToTicks(REFRESH_INTERVAL) ) { // allow a few ticks to ensure the next OCR1A not missed 98 | tc->TC_CHANNEL[channel].TC_RA = (unsigned int)usToTicks(REFRESH_INTERVAL); 99 | } 100 | else { 101 | tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + 4; // at least REFRESH_INTERVAL has elapsed 102 | } 103 | Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel 104 | } 105 | } 106 | 107 | static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) 108 | { 109 | pmc_enable_periph_clk(id); 110 | TC_Configure(tc, channel, 111 | TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32 112 | TC_CMR_WAVE | // Waveform mode 113 | TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC 114 | 115 | /* 84MHz, MCK/32, for 1.5ms: 3937 */ 116 | TC_SetRA(tc, channel, 2625); // 1ms 117 | 118 | /* Configure and enable interrupt */ 119 | NVIC_EnableIRQ(irqn); 120 | // TC_IER_CPAS: RA Compare 121 | tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS; 122 | 123 | // Enables the timer clock and performs a software reset to start the counting 124 | TC_Start(tc, channel); 125 | } 126 | 127 | static void initISR(timer16_Sequence_t timer) 128 | { 129 | #if defined (_useTimer1) 130 | if (timer == _timer1) 131 | _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1); 132 | #endif 133 | #if defined (_useTimer2) 134 | if (timer == _timer2) 135 | _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2); 136 | #endif 137 | #if defined (_useTimer3) 138 | if (timer == _timer3) 139 | _initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3); 140 | #endif 141 | #if defined (_useTimer4) 142 | if (timer == _timer4) 143 | _initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4); 144 | #endif 145 | #if defined (_useTimer5) 146 | if (timer == _timer5) 147 | _initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5); 148 | #endif 149 | } 150 | 151 | static void finISR(timer16_Sequence_t timer) 152 | { 153 | #if defined (_useTimer1) 154 | TC_Stop(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); 155 | #endif 156 | #if defined (_useTimer2) 157 | TC_Stop(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2); 158 | #endif 159 | #if defined (_useTimer3) 160 | TC_Stop(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3); 161 | #endif 162 | #if defined (_useTimer4) 163 | TC_Stop(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4); 164 | #endif 165 | #if defined (_useTimer5) 166 | TC_Stop(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); 167 | #endif 168 | } 169 | 170 | 171 | static boolean isTimerActive(timer16_Sequence_t timer) 172 | { 173 | // returns true if any servo is active on this timer 174 | for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { 175 | if(SERVO(timer,channel).Pin.isActive == true) 176 | return true; 177 | } 178 | return false; 179 | } 180 | 181 | /****************** end of static functions ******************************/ 182 | 183 | Servo::Servo() 184 | { 185 | if (ServoCount < MAX_SERVOS) { 186 | this->servoIndex = ServoCount++; // assign a servo index to this instance 187 | servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values 188 | } else { 189 | this->servoIndex = INVALID_SERVO; // too many servos 190 | } 191 | } 192 | 193 | uint8_t Servo::attach(int pin) 194 | { 195 | return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); 196 | } 197 | 198 | uint8_t Servo::attach(int pin, int min, int max) 199 | { 200 | timer16_Sequence_t timer; 201 | 202 | if (this->servoIndex < MAX_SERVOS) { 203 | pinMode(pin, OUTPUT); // set servo pin to output 204 | servos[this->servoIndex].Pin.nbr = pin; 205 | // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 206 | this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS 207 | this->max = (MAX_PULSE_WIDTH - max)/4; 208 | // initialize the timer if it has not already been initialized 209 | timer = SERVO_INDEX_TO_TIMER(servoIndex); 210 | if (isTimerActive(timer) == false) { 211 | initISR(timer); 212 | } 213 | servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive 214 | } 215 | return this->servoIndex; 216 | } 217 | 218 | void Servo::detach() 219 | { 220 | timer16_Sequence_t timer; 221 | 222 | servos[this->servoIndex].Pin.isActive = false; 223 | timer = SERVO_INDEX_TO_TIMER(servoIndex); 224 | if(isTimerActive(timer) == false) { 225 | finISR(timer); 226 | } 227 | } 228 | 229 | void Servo::write(int value) 230 | { 231 | // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) 232 | if (value < MIN_PULSE_WIDTH) 233 | { 234 | if (value < 0) 235 | value = 0; 236 | else if (value > 180) 237 | value = 180; 238 | 239 | value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); 240 | } 241 | writeMicroseconds(value); 242 | } 243 | 244 | void Servo::writeMicroseconds(int value) 245 | { 246 | // calculate and store the values for the given channel 247 | byte channel = this->servoIndex; 248 | if( (channel < MAX_SERVOS) ) // ensure channel is valid 249 | { 250 | if (value < SERVO_MIN()) // ensure pulse width is valid 251 | value = SERVO_MIN(); 252 | else if (value > SERVO_MAX()) 253 | value = SERVO_MAX(); 254 | 255 | value = value - TRIM_DURATION; 256 | value = usToTicks(value); // convert to ticks after compensating for interrupt overhead 257 | servos[channel].ticks = value; 258 | } 259 | } 260 | 261 | int Servo::read() // return the value as degrees 262 | { 263 | return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); 264 | } 265 | 266 | int Servo::readMicroseconds() 267 | { 268 | unsigned int pulsewidth; 269 | if (this->servoIndex != INVALID_SERVO) 270 | pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; 271 | else 272 | pulsewidth = 0; 273 | 274 | return pulsewidth; 275 | } 276 | 277 | bool Servo::attached() 278 | { 279 | return servos[this->servoIndex].Pin.isActive; 280 | } 281 | 282 | #endif // ARDUINO_ARCH_SAM 283 | 284 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/src/sam/ServoTimers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2013 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /* 20 | * Defines for 16 bit timers used with Servo library 21 | * 22 | * If _useTimerX is defined then TimerX is a 16 bit timer on the current board 23 | * timer16_Sequence_t enumerates the sequence that the timers should be allocated 24 | * _Nbr_16timers indicates how many 16 bit timers are available. 25 | */ 26 | 27 | /** 28 | * SAM Only definitions 29 | * -------------------- 30 | */ 31 | 32 | // For SAM3X: 33 | #define _useTimer1 34 | #define _useTimer2 35 | #define _useTimer3 36 | #define _useTimer4 37 | #define _useTimer5 38 | 39 | /* 40 | TC0, chan 0 => TC0_Handler 41 | TC0, chan 1 => TC1_Handler 42 | TC0, chan 2 => TC2_Handler 43 | TC1, chan 0 => TC3_Handler 44 | TC1, chan 1 => TC4_Handler 45 | TC1, chan 2 => TC5_Handler 46 | TC2, chan 0 => TC6_Handler 47 | TC2, chan 1 => TC7_Handler 48 | TC2, chan 2 => TC8_Handler 49 | */ 50 | 51 | #if defined (_useTimer1) 52 | #define TC_FOR_TIMER1 TC1 53 | #define CHANNEL_FOR_TIMER1 0 54 | #define ID_TC_FOR_TIMER1 ID_TC3 55 | #define IRQn_FOR_TIMER1 TC3_IRQn 56 | #define HANDLER_FOR_TIMER1 TC3_Handler 57 | #endif 58 | #if defined (_useTimer2) 59 | #define TC_FOR_TIMER2 TC1 60 | #define CHANNEL_FOR_TIMER2 1 61 | #define ID_TC_FOR_TIMER2 ID_TC4 62 | #define IRQn_FOR_TIMER2 TC4_IRQn 63 | #define HANDLER_FOR_TIMER2 TC4_Handler 64 | #endif 65 | #if defined (_useTimer3) 66 | #define TC_FOR_TIMER3 TC1 67 | #define CHANNEL_FOR_TIMER3 2 68 | #define ID_TC_FOR_TIMER3 ID_TC5 69 | #define IRQn_FOR_TIMER3 TC5_IRQn 70 | #define HANDLER_FOR_TIMER3 TC5_Handler 71 | #endif 72 | #if defined (_useTimer4) 73 | #define TC_FOR_TIMER4 TC0 74 | #define CHANNEL_FOR_TIMER4 2 75 | #define ID_TC_FOR_TIMER4 ID_TC2 76 | #define IRQn_FOR_TIMER4 TC2_IRQn 77 | #define HANDLER_FOR_TIMER4 TC2_Handler 78 | #endif 79 | #if defined (_useTimer5) 80 | #define TC_FOR_TIMER5 TC0 81 | #define CHANNEL_FOR_TIMER5 0 82 | #define ID_TC_FOR_TIMER5 ID_TC0 83 | #define IRQn_FOR_TIMER5 TC0_IRQn 84 | #define HANDLER_FOR_TIMER5 TC0_Handler 85 | #endif 86 | 87 | typedef enum { _timer1, _timer2, _timer3, _timer4, _timer5, _Nbr_16timers } timer16_Sequence_t ; 88 | 89 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/src/samd/Servo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | #if defined(ARDUINO_ARCH_SAMD) 20 | 21 | #include 22 | #include 23 | 24 | #define usToTicks(_us) ((clockCyclesPerMicrosecond() * _us) / 16) // converts microseconds to tick 25 | #define ticksToUs(_ticks) (((unsigned) _ticks * 16) / clockCyclesPerMicrosecond()) // converts from ticks back to microseconds 26 | 27 | #define TRIM_DURATION 5 // compensation ticks to trim adjust for digitalWrite delays 28 | 29 | static servo_t servos[MAX_SERVOS]; // static array of servo structures 30 | 31 | uint8_t ServoCount = 0; // the total number of attached servos 32 | 33 | static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval) 34 | 35 | // convenience macros 36 | #define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / SERVOS_PER_TIMER)) // returns the timer controlling this servo 37 | #define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % SERVOS_PER_TIMER) // returns the index of the servo on this timer 38 | #define SERVO_INDEX(_timer,_channel) ((_timer*SERVOS_PER_TIMER) + _channel) // macro to access servo index by timer and channel 39 | #define SERVO(_timer,_channel) (servos[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel 40 | 41 | #define SERVO_MIN() (MIN_PULSE_WIDTH - this->min * 4) // minimum value in uS for this servo 42 | #define SERVO_MAX() (MAX_PULSE_WIDTH - this->max * 4) // maximum value in uS for this servo 43 | 44 | #define WAIT_TC16_REGS_SYNC(x) while(x->COUNT16.STATUS.bit.SYNCBUSY); 45 | 46 | /************ static functions common to all instances ***********************/ 47 | 48 | void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel, uint8_t intFlag); 49 | #if defined (_useTimer1) 50 | void HANDLER_FOR_TIMER1(void) { 51 | Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, INTFLAG_BIT_FOR_TIMER_1); 52 | } 53 | #endif 54 | #if defined (_useTimer2) 55 | void HANDLER_FOR_TIMER2(void) { 56 | Servo_Handler(_timer2, TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, INTFLAG_BIT_FOR_TIMER_2); 57 | } 58 | #endif 59 | 60 | void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel, uint8_t intFlag) 61 | { 62 | if (currentServoIndex[timer] < 0) { 63 | tc->COUNT16.COUNT.reg = (uint16_t) 0; 64 | WAIT_TC16_REGS_SYNC(tc) 65 | } else { 66 | if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { 67 | digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated 68 | } 69 | } 70 | 71 | // Select the next servo controlled by this timer 72 | currentServoIndex[timer]++; 73 | 74 | if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) { 75 | if (SERVO(timer, currentServoIndex[timer]).Pin.isActive == true) { // check if activated 76 | digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high 77 | } 78 | 79 | // Get the counter value 80 | uint16_t tcCounterValue = tc->COUNT16.COUNT.reg; 81 | WAIT_TC16_REGS_SYNC(tc) 82 | 83 | tc->COUNT16.CC[channel].reg = (uint16_t) (tcCounterValue + SERVO(timer, currentServoIndex[timer]).ticks); 84 | WAIT_TC16_REGS_SYNC(tc) 85 | } 86 | else { 87 | // finished all channels so wait for the refresh period to expire before starting over 88 | 89 | // Get the counter value 90 | uint16_t tcCounterValue = tc->COUNT16.COUNT.reg; 91 | WAIT_TC16_REGS_SYNC(tc) 92 | 93 | if (tcCounterValue + 4UL < usToTicks(REFRESH_INTERVAL)) { // allow a few ticks to ensure the next OCR1A not missed 94 | tc->COUNT16.CC[channel].reg = (uint16_t) usToTicks(REFRESH_INTERVAL); 95 | } 96 | else { 97 | tc->COUNT16.CC[channel].reg = (uint16_t) (tcCounterValue + 4UL); // at least REFRESH_INTERVAL has elapsed 98 | } 99 | WAIT_TC16_REGS_SYNC(tc) 100 | 101 | currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel 102 | } 103 | 104 | // Clear the interrupt 105 | tc->COUNT16.INTFLAG.reg = intFlag; 106 | } 107 | 108 | static inline void resetTC (Tc* TCx) 109 | { 110 | // Disable TCx 111 | TCx->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE; 112 | WAIT_TC16_REGS_SYNC(TCx) 113 | 114 | // Reset TCx 115 | TCx->COUNT16.CTRLA.reg = TC_CTRLA_SWRST; 116 | WAIT_TC16_REGS_SYNC(TCx) 117 | while (TCx->COUNT16.CTRLA.bit.SWRST); 118 | } 119 | 120 | static void _initISR(Tc *tc, uint8_t channel, uint32_t id, IRQn_Type irqn, uint8_t gcmForTimer, uint8_t intEnableBit) 121 | { 122 | // Enable GCLK for timer 1 (timer counter input clock) 123 | GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(gcmForTimer)); 124 | while (GCLK->STATUS.bit.SYNCBUSY); 125 | 126 | // Reset the timer 127 | // TODO this is not the right thing to do if more than one channel per timer is used by the Servo library 128 | resetTC(tc); 129 | 130 | // Set timer counter mode to 16 bits 131 | tc->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16; 132 | 133 | // Set timer counter mode as normal PWM 134 | tc->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM; 135 | 136 | // Set the prescaler factor to GCLK_TC/16. At nominal 48MHz GCLK_TC this is 3000 ticks per millisecond 137 | tc->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV16; 138 | 139 | // Count up 140 | tc->COUNT16.CTRLBCLR.bit.DIR = 1; 141 | WAIT_TC16_REGS_SYNC(tc) 142 | 143 | // First interrupt request after 1 ms 144 | tc->COUNT16.CC[channel].reg = (uint16_t) usToTicks(1000UL); 145 | WAIT_TC16_REGS_SYNC(tc) 146 | 147 | // Configure interrupt request 148 | // TODO this should be changed if more than one channel per timer is used by the Servo library 149 | NVIC_DisableIRQ(irqn); 150 | NVIC_ClearPendingIRQ(irqn); 151 | NVIC_SetPriority(irqn, 0); 152 | NVIC_EnableIRQ(irqn); 153 | 154 | // Enable the match channel interrupt request 155 | tc->COUNT16.INTENSET.reg = intEnableBit; 156 | 157 | // Enable the timer and start it 158 | tc->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; 159 | WAIT_TC16_REGS_SYNC(tc) 160 | } 161 | 162 | static void initISR(timer16_Sequence_t timer) 163 | { 164 | #if defined (_useTimer1) 165 | if (timer == _timer1) 166 | _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1, GCM_FOR_TIMER_1, INTENSET_BIT_FOR_TIMER_1); 167 | #endif 168 | #if defined (_useTimer2) 169 | if (timer == _timer2) 170 | _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2, GCM_FOR_TIMER_2, INTENSET_BIT_FOR_TIMER_2); 171 | #endif 172 | } 173 | 174 | static void finISR(timer16_Sequence_t timer) 175 | { 176 | #if defined (_useTimer1) 177 | // Disable the match channel interrupt request 178 | TC_FOR_TIMER1->COUNT16.INTENCLR.reg = INTENCLR_BIT_FOR_TIMER_1; 179 | #endif 180 | #if defined (_useTimer2) 181 | // Disable the match channel interrupt request 182 | TC_FOR_TIMER2->COUNT16.INTENCLR.reg = INTENCLR_BIT_FOR_TIMER_2; 183 | #endif 184 | } 185 | 186 | static boolean isTimerActive(timer16_Sequence_t timer) 187 | { 188 | // returns true if any servo is active on this timer 189 | for(uint8_t channel=0; channel < SERVOS_PER_TIMER; channel++) { 190 | if(SERVO(timer,channel).Pin.isActive == true) 191 | return true; 192 | } 193 | return false; 194 | } 195 | 196 | /****************** end of static functions ******************************/ 197 | 198 | Servo::Servo() 199 | { 200 | if (ServoCount < MAX_SERVOS) { 201 | this->servoIndex = ServoCount++; // assign a servo index to this instance 202 | servos[this->servoIndex].ticks = usToTicks(DEFAULT_PULSE_WIDTH); // store default values 203 | } else { 204 | this->servoIndex = INVALID_SERVO; // too many servos 205 | } 206 | } 207 | 208 | uint8_t Servo::attach(int pin) 209 | { 210 | return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH); 211 | } 212 | 213 | uint8_t Servo::attach(int pin, int min, int max) 214 | { 215 | timer16_Sequence_t timer; 216 | 217 | if (this->servoIndex < MAX_SERVOS) { 218 | pinMode(pin, OUTPUT); // set servo pin to output 219 | servos[this->servoIndex].Pin.nbr = pin; 220 | // todo min/max check: abs(min - MIN_PULSE_WIDTH) /4 < 128 221 | this->min = (MIN_PULSE_WIDTH - min)/4; //resolution of min/max is 4 uS 222 | this->max = (MAX_PULSE_WIDTH - max)/4; 223 | // initialize the timer if it has not already been initialized 224 | timer = SERVO_INDEX_TO_TIMER(servoIndex); 225 | if (isTimerActive(timer) == false) { 226 | initISR(timer); 227 | } 228 | servos[this->servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive 229 | } 230 | return this->servoIndex; 231 | } 232 | 233 | void Servo::detach() 234 | { 235 | timer16_Sequence_t timer; 236 | 237 | servos[this->servoIndex].Pin.isActive = false; 238 | timer = SERVO_INDEX_TO_TIMER(servoIndex); 239 | if(isTimerActive(timer) == false) { 240 | finISR(timer); 241 | } 242 | } 243 | 244 | void Servo::write(int value) 245 | { 246 | // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) 247 | if (value < MIN_PULSE_WIDTH) 248 | { 249 | if (value < 0) 250 | value = 0; 251 | else if (value > 180) 252 | value = 180; 253 | 254 | value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); 255 | } 256 | writeMicroseconds(value); 257 | } 258 | 259 | void Servo::writeMicroseconds(int value) 260 | { 261 | // calculate and store the values for the given channel 262 | byte channel = this->servoIndex; 263 | if( (channel < MAX_SERVOS) ) // ensure channel is valid 264 | { 265 | if (value < SERVO_MIN()) // ensure pulse width is valid 266 | value = SERVO_MIN(); 267 | else if (value > SERVO_MAX()) 268 | value = SERVO_MAX(); 269 | 270 | value = value - TRIM_DURATION; 271 | value = usToTicks(value); // convert to ticks after compensating for interrupt overhead 272 | servos[channel].ticks = value; 273 | } 274 | } 275 | 276 | int Servo::read() // return the value as degrees 277 | { 278 | return map(readMicroseconds()+1, SERVO_MIN(), SERVO_MAX(), 0, 180); 279 | } 280 | 281 | int Servo::readMicroseconds() 282 | { 283 | unsigned int pulsewidth; 284 | if (this->servoIndex != INVALID_SERVO) 285 | pulsewidth = ticksToUs(servos[this->servoIndex].ticks) + TRIM_DURATION; 286 | else 287 | pulsewidth = 0; 288 | 289 | return pulsewidth; 290 | } 291 | 292 | bool Servo::attached() 293 | { 294 | return servos[this->servoIndex].Pin.isActive; 295 | } 296 | 297 | #endif // ARDUINO_ARCH_SAMD 298 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/Servo/src/samd/ServoTimers.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015 Arduino LLC. All right reserved. 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 17 | */ 18 | 19 | /* 20 | * Defines for 16 bit timers used with Servo library 21 | * 22 | * If _useTimerX is defined then TimerX is a 16 bit timer on the current board 23 | * timer16_Sequence_t enumerates the sequence that the timers should be allocated 24 | * _Nbr_16timers indicates how many 16 bit timers are available. 25 | */ 26 | 27 | #ifndef __SERVO_TIMERS_H__ 28 | #define __SERVO_TIMERS_H__ 29 | 30 | /** 31 | * SAMD Only definitions 32 | * --------------------- 33 | */ 34 | 35 | // For SAMD: 36 | #define _useTimer1 37 | //#define _useTimer2 // <- TODO do not activate until the code in Servo.cpp has been changed in order 38 | // to manage more than one channel per timer on the SAMD architecture 39 | 40 | #if defined (_useTimer1) 41 | #define TC_FOR_TIMER1 TC4 42 | #define CHANNEL_FOR_TIMER1 0 43 | #define INTENSET_BIT_FOR_TIMER_1 TC_INTENSET_MC0 44 | #define INTENCLR_BIT_FOR_TIMER_1 TC_INTENCLR_MC0 45 | #define INTFLAG_BIT_FOR_TIMER_1 TC_INTFLAG_MC0 46 | #define ID_TC_FOR_TIMER1 ID_TC4 47 | #define IRQn_FOR_TIMER1 TC4_IRQn 48 | #define HANDLER_FOR_TIMER1 TC4_Handler 49 | #define GCM_FOR_TIMER_1 GCM_TC4_TC5 50 | #endif 51 | #if defined (_useTimer2) 52 | #define TC_FOR_TIMER2 TC4 53 | #define CHANNEL_FOR_TIMER2 1 54 | #define INTENSET_BIT_FOR_TIMER_2 TC_INTENSET_MC1 55 | #define INTENCLR_BIT_FOR_TIMER_2 TC_INTENCLR_MC1 56 | #define ID_TC_FOR_TIMER2 ID_TC4 57 | #define IRQn_FOR_TIMER2 TC4_IRQn 58 | #define HANDLER_FOR_TIMER2 TC4_Handler 59 | #define GCM_FOR_TIMER_2 GCM_TC4_TC5 60 | #endif 61 | 62 | typedef enum { 63 | #if defined (_useTimer1) 64 | _timer1, 65 | #endif 66 | #if defined (_useTimer2) 67 | _timer2, 68 | #endif 69 | _Nbr_16timers } timer16_Sequence_t; 70 | 71 | #endif // __SERVO_TIMERS_H__ 72 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/motor/motor.cpp: -------------------------------------------------------------------------------- 1 | /*library tested 30 NOVEMBER 2 | Made by Deep Goel and Kartik Gupta 3 | */ 4 | 5 | #include 6 | //#include 7 | #include 8 | Motor::Motor() //constructor 9 | { 10 | attachMotor(-1,-1,-1); 11 | } 12 | 13 | Motor::Motor(int Dir1, int Dir2, int Pwm ) // parametrised constructor 14 | { 15 | attachMotor(Dir1,Dir2,Pwm); 16 | } 17 | 18 | void Motor::attachMotor(int Dir1,int Dir2,int Pwm) 19 | { 20 | pwm_pin= Pwm; 21 | dir1_pin = Dir1; 22 | dir2_pin = Dir2; 23 | if(dir1!=-1 && dir2!=-1 && pwm_pin!=-1) 24 | { 25 | pinMode(pwm_pin,OUTPUT); 26 | pinMode(dir1_pin,OUTPUT); 27 | pinMode(dir2_pin,OUTPUT); 28 | } 29 | pwm = 0; 30 | speed = 0; 31 | mean_speed = 255; 32 | //lockMotor(); //Lock the Motor initially 33 | damping=10; 34 | } 35 | 36 | 37 | void Motor::moveMotor(int Pwm) //+ve for CW and -ve for CCW. 38 | { 39 | 40 | if(Pwm>=0) 41 | { 42 | digitalWrite(dir1_pin,HIGH); 43 | digitalWrite(dir2_pin,LOW); 44 | } 45 | else 46 | { 47 | digitalWrite(dir1_pin,LOW); 48 | digitalWrite(dir2_pin,HIGH); 49 | } 50 | changePWM(Pwm); 51 | // Serial.println("PWM="); 52 | // Serial.print(Pwm); 53 | } 54 | 55 | void Motor::moveMotor(int Dir1,int Dir2,int Pwm) 56 | { 57 | if(Dir1==1 && Dir2==0) 58 | moveMotor(Pwm); 59 | if(Dir1==0 && Dir2==1) 60 | moveMotor(-Pwm); 61 | } 62 | 63 | void Motor::stopMotor() //By default stop motor will lock motor 64 | { 65 | lockMotor(); 66 | } 67 | 68 | void Motor::lockMotor() 69 | { 70 | digitalWrite(dir1_pin,HIGH); //case of motor lock 71 | digitalWrite(dir2_pin,HIGH); 72 | analogWrite(pwm_pin,255); 73 | pwm=0; 74 | } 75 | 76 | void Motor::freeMotor() 77 | { 78 | digitalWrite(dir1_pin,LOW); //case of motor free 79 | digitalWrite(dir2_pin,LOW); 80 | analogWrite(pwm_pin,0); 81 | pwm=0; 82 | } 83 | 84 | void Motor::setMeanSpeed(int Speed) //Sets the meanspeed with which motor moves when speed=100% 85 | { 86 | mean_speed=Speed; 87 | } 88 | 89 | void Motor::setMotorSpeed(int Speed) //+ve for CW and -ve for CCW. Speed in percentage of meanspeed 90 | { 91 | if(Speed>100) 92 | Speed=100; 93 | if(Speed<-100) 94 | Speed=-100; 95 | speed=Speed; 96 | 97 | moveMotor(Speed*mean_speed/100); 98 | } 99 | 100 | void Motor::setMotorSpeed(int Dir1,int Dir2,int Speed) 101 | { 102 | if(Speed>100) 103 | Speed=100; 104 | if(Speed<-100) 105 | Speed=-100; 106 | speed=Speed; 107 | moveMotor(Dir1,Dir2,Speed*mean_speed/100); 108 | } 109 | 110 | void Motor::changePWM(int Pwm) //Just to change the PWM 111 | { 112 | pwm = Pwm>255 ? 255 : (Pwm < -255 ? -255 :Pwm); 113 | analogWrite(pwm_pin,abs(pwm)); 114 | } 115 | 116 | void Motor::changeSpeed(int Speed) //Just to change the speed (In percentage) 117 | { 118 | if(Speed>100) 119 | Speed=100; 120 | if(Speed<-100) 121 | Speed=-100; 122 | speed=Speed; 123 | changePWM(Speed*mean_speed/100); 124 | } 125 | 126 | int Motor::getDirection() 127 | { 128 | dir1=digitalRead(dir1_pin); 129 | dir2=digitalRead(dir2_pin); 130 | if (dir1==dir2) 131 | return 0; 132 | else 133 | return((dir1>dir2)?1:-1); 134 | } 135 | 136 | int Motor::isFree() 137 | { 138 | return (getDirection()==0 && dir1==0); 139 | } 140 | 141 | int Motor::isLocked() 142 | { 143 | return (getDirection()==0 && dir1==1); 144 | } 145 | 146 | int Motor::getSpeed() 147 | { 148 | return(pwm*100/mean_speed); 149 | } 150 | 151 | int Motor::getPWM() 152 | { 153 | return pwm; 154 | } 155 | 156 | void Motor::startSmoothly(int Speed) 157 | { 158 | if(Speed>100) 159 | Speed=100; 160 | if(Speed<-100) 161 | Speed=-100; 162 | int i; 163 | if(Speed>=0) 164 | { 165 | digitalWrite(dir1_pin,HIGH); 166 | digitalWrite(dir2_pin,LOW); 167 | } 168 | else 169 | { 170 | digitalWrite(dir1_pin,LOW); 171 | digitalWrite(dir2_pin,HIGH); 172 | } 173 | for(i=0;i<=Speed;i=i+COUNT_CONST) 174 | { 175 | changeSpeed(i); 176 | delay(COUNT_CONST*damping); 177 | speed=i; 178 | pwm=speed*mean_speed/100; 179 | } 180 | } 181 | void Motor::stopSmoothly() 182 | { int i; 183 | speed=getSpeed(); 184 | for(i=speed;i>=0;i=i-COUNT_CONST) 185 | { 186 | changeSpeed(i); 187 | delay(COUNT_CONST*damping); 188 | speed=i; 189 | pwm=speed*mean_speed/100; 190 | } 191 | lockMotor(); 192 | } 193 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/motor/motor.h: -------------------------------------------------------------------------------- 1 | /*library tested 30 NOVEMBER 2 | Made by Deep Goel and Kartik Gupta 3 | */ 4 | #ifndef MOTOR_H 5 | #define MOTOR_H 6 | // 7 | //(imp) motor will be considered cw if dir1 is HIGH and DIR2 is LOW 8 | // 9 | 10 | 11 | #ifndef COUNT_CONST 12 | #define COUNT_CONST 3 13 | 14 | #endif //for COUNT_CONST 15 | class Motor 16 | { 17 | // private: 18 | 19 | 20 | public: 21 | // Variables 22 | 23 | int dir1_pin; //stores pin no of direction1 24 | int dir2_pin; //stores pin no of direction2 25 | int pwm_pin; //stores pin no of pwm pin 26 | int dir1; //stores value of DIR1PIN as 1 or 0 27 | int dir2; //stores value of DIR2PIN as 1 or 0 28 | int pwm; //pwm: Stores the pwm value given to the motor 29 | int mean_speed; //mean_speed : The value to which motor moves when speed=100% 30 | float speed; //speed : Speed of the motor in percentage of meanspeed 31 | int damping; //to be changed later by trial 32 | 33 | // Functions 34 | public: 35 | Motor(); //constructor 36 | Motor(int Dir1,int Dir2,int Pwm); //constructor with attachments of pins 37 | void attachMotor(int Dir1,int Dir2,int Pwm); //attachments of pins 38 | void moveMotor(int Pwm); //+ve for CW and -ve for CCW. 39 | void moveMotor(int Dir1,int Dir2,int Pwm); // dir1 and dir2 can be 1 or 0,pwm can only be +ve for CW 40 | void stopMotor(); //By default stop motor will lock motor 41 | void lockMotor(); //To lock the motor 42 | void freeMotor(); //Free the motor 43 | void setMeanSpeed(int Speed); //Sets the meanspeed with which motor moves when speed=100% 44 | void setMotorSpeed(int Speed); //+ve for CW and -ve for CCW. Speed in percentage of meanspeed 45 | void setMotorSpeed(int Dir1,int Dir2,int Speed); // dir1 and dir2 can be 1 or 0 46 | void changePWM(int Pwm); //Just to change the PWM in whatever direction the motor was moving 47 | void changeSpeed(int Speed); //Just to change the speed (In percentage) not the direction 48 | int getDirection(); //+1 for cw and -1 for ccw and 0 for free or locked 49 | int isFree(); //+1 for free and 0 for not free 50 | int isLocked(); //+1 for locked and 0 for not locked 51 | int getSpeed(); // returns speed in % of mean speed 52 | int getPWM(); // returns +ve for CW and -ve for CCW. 53 | void startSmoothly(int Speed); //+ve for CW and -ve for CCW. 54 | void stopSmoothly(); 55 | }; 56 | #endif 57 | -------------------------------------------------------------------------------- /obstacleAvoidanceRobot/obstacleAvoidance/obstacleAvoidance.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | *date-2/6/2016 4 | *developed by- Madhukant (kantmadhu956@gmail.com) & Tushar Gupta(tushargupta5197@gmail.com ) 5 | */ 6 | #include // Core graphics library 7 | #include // Hardware-specific library 8 | #include 9 | 10 | #define TFT_CS 48 11 | #define TFT_RST 47 // you can also connect this to the Arduino reset 12 | // in which case, set this #define pin to 0! 13 | #define TFT_DC 49 14 | 15 | Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 16 | 17 | 18 | #include 19 | 20 | #include 21 | 22 | Motor left(29,28,44); 23 | Motor right(30,31,45); 24 | 25 | int i; 26 | int meanspeed=220; 27 | int speedleft=meanspeed; 28 | int speedright=meanspeed; 29 | 30 | #define trigPin 3 // pins for ultrasonic sensor 31 | #define echoPin 2 32 | 33 | int limit=20; 34 | int factor=30; 35 | 36 | Servo servo; // declare your servo as an object 37 | 38 | void setup() { 39 | Serial.begin (9600); 40 | servo.attach(9); // telling the ide that the servo is at pin 9 41 | pinMode(40,INPUT); // Setting a slideswitch of evive as on/off button 42 | tft.initR(INITR_BLACKTAB); 43 | tft.fillScreen(ST7735_BLACK); 44 | tft.setRotation(1); 45 | tft.setCursor(0,0); 46 | pinMode(trigPin, OUTPUT); 47 | pinMode(echoPin, INPUT); 48 | tft.setTextColor(ST7735_YELLOW,ST7735_BLACK); 49 | } 50 | int leftd,rightd; // to store distances towards left and right 51 | int dist() // to find the distance via the ultrasonic sensor 52 | { 53 | long duration, distance; 54 | digitalWrite(trigPin, LOW); // Added this line 55 | delayMicroseconds(2); // Added this line 56 | digitalWrite(trigPin, HIGH); 57 | // delayMicroseconds(1000); - Removed this line 58 | delayMicroseconds(10); // Added this line 59 | digitalWrite(trigPin, LOW); 60 | duration = pulseIn(echoPin, HIGH); 61 | distance = (duration/2) / 29.1; 62 | tft.setCursor(0,0); 63 | tft.print(distance); 64 | return distance; 65 | } 66 | int turn; 67 | int scan() // scanning the left and right sides before turning 68 | { 69 | servo.write(60); 70 | delay(300); 71 | leftd=dist(); 72 | tft.setCursor(50,0); 73 | tft.print(leftd); 74 | servo.write(120); 75 | delay(300); 76 | rightd=dist(); 77 | tft.print(rightd); 78 | if(leftd>rightd) // emptier in left 79 | return -1; 80 | else return 1; // emptier in right 81 | } 82 | void loop() { 83 | if(digitalRead(40)==HIGH) //On/off switch 84 | { 85 | int forward; 86 | forward=dist(); 87 | Serial.println(forward); 88 | tft.setCursor(0,0); 89 | tft.print(forward); 90 | left.moveMotor(speedleft); 91 | right.moveMotor(speedright); 92 | //delay(1000); 93 | while(dist() // Core graphics library 15 | #include // Hardware-specific library 16 | #include 17 | 18 | #include "bitmaps.h" 19 | #include "bitmapsLarge.h" 20 | 21 | // For the breakout, you can use any 2 or 3 pins 22 | // These pins will also work for the 1.8" TFT shield 23 | // TFT is internally connected to Arduino MEGA in evive 24 | #define TFT_CS 48 25 | #define TFT_RST 47 26 | #define TFT_DC 49 27 | 28 | //initialize a tft variable 29 | Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 30 | 31 | //********************alarm clock initiasation*********************** 32 | #include "Wire.h" 33 | #define PCF8563address 0x51 34 | 35 | #define alarmOnOff 40 36 | #define alarmHand A9 37 | #define buzzerPin 46 38 | // calender function variables 39 | byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; 40 | String days[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" }; 41 | 42 | byte secondOlympics = 0, minuteOlympics = 0, hourOlympics = 15; 43 | 44 | byte bcdToDec(byte value) 45 | { 46 | return ((value / 16) * 10 + value % 16); 47 | } 48 | 49 | byte decToBcd(byte value){ 50 | return (value / 10 * 16 + value % 10); 51 | } 52 | 53 | void setPCF8563() 54 | // this sets the time and date to the PCF8563 55 | { 56 | Wire.beginTransmission(PCF8563address); 57 | Wire.write(0x02); 58 | Wire.write(decToBcd(second)); //second 59 | Wire.write(decToBcd(minute)); //minute 60 | Wire.write(decToBcd(hour)); //hour 61 | Wire.write(decToBcd(dayOfMonth)); //date 62 | Wire.write(decToBcd(dayOfWeek)); //day of week see_the_above array 63 | Wire.write(decToBcd(month)); //month 64 | Wire.write(decToBcd(year)); //year 65 | Wire.endTransmission(); 66 | } 67 | 68 | // Gets the time and date from the PCF8563 69 | void readPCF8563() 70 | { 71 | Wire.beginTransmission(PCF8563address); 72 | Wire.write(0x02); 73 | Wire.endTransmission(); 74 | Wire.requestFrom(PCF8563address, 7); 75 | second = bcdToDec(Wire.read() & B01111111); // remove VL error bit 76 | minute = bcdToDec(Wire.read() & B01111111); // remove unwanted bits from MSB 77 | hour = bcdToDec(Wire.read() & B00111111); 78 | dayOfMonth = bcdToDec(Wire.read() & B00111111); 79 | dayOfWeek = bcdToDec(Wire.read() & B00000111); 80 | month = bcdToDec(Wire.read() & B00011111); // remove century bit, 1999 is over 81 | year = bcdToDec(Wire.read()); 82 | } 83 | 84 | //Initialize angles of clock hands 85 | float hangle=0; 86 | float mangle=0; 87 | float sangle=0; 88 | float aangle=0,paangle=0; 89 | 90 | int i=0; 91 | 92 | void setup(){ 93 | //*************************clock setup***************** 94 | tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab 95 | 96 | tft.fillScreen(ST7735_BLACK); 97 | 98 | tft.setRotation(1); 99 | tft.setTextWrap(false); // Allow text to run off right edge 100 | //tft.fillScreen(ST7735_BLACK); 101 | //***************clock setup end ********************** 102 | Wire.begin(); 103 | Serial.begin(9600); 104 | pinMode(alarmOnOff,INPUT); 105 | 106 | //Change the following to set your initial time 107 | second = 0; //0-59 108 | minute = 25; //0-59 109 | hour = 9; //0-23 110 | dayOfWeek = 5; //0-6 111 | dayOfMonth = 5; //1-31 (includes Leap year correction by having 29th Feb) 112 | month = 8; //1-12 113 | year = 16; //0-99 114 | 115 | //Comment out the next line and upload again to set and keep the time from resetting every reset 116 | //setPCF8563(); 117 | 118 | // int alarmpot=A9; 119 | //pinMode(39,INPUT); 120 | pinMode(buzzerPin,OUTPUT); 121 | 122 | //Case 2: Multi Colored Images/Icons 123 | int h = 66,w = 160, row, col, buffidx=0; 124 | for (row=0; row 6 | 7 | #define limit1 500 8 | #define limit2 900 9 | Motor pump(29,28,44); 10 | int speedg =250; 11 | int soilpin=A4; 12 | int msgflag=0; 13 | void setup() { 14 | Serial.begin(9600); 15 | Serial3.begin(115200); 16 | Serial3.println("AT+CWMODE=2"); 17 | delay(500); 18 | } 19 | int flag=0; 20 | long t=millis(); 21 | String reading=""; 22 | void loop() { 23 | int moisture=map(analogRead(soilpin),0,1023,0,9); 24 | if (Serial3.available()){ 25 | while (Serial3.available()){ 26 | char c=Serial3.read(); 27 | Serial.write(c); 28 | } 29 | } 30 | if (Serial.available()){ 31 | delay(1000); 32 | String command=""; 33 | while (Serial.available()){ 34 | command+=(char)Serial.read(); 35 | } 36 | Serial3.println(command); 37 | if(command=="AT+CIPSERVER=1,1338") 38 | flag=1; 39 | 40 | } 41 | while(flag==1) 42 | { 43 | reading="\b\b"; 44 | if(msgflag==1) 45 | reading+=(String)moisture; 46 | reading=reading+" \n"; 47 | Serial3.print("AT+CIPSEND=0,"); 48 | Serial3.println(reading.length()); 49 | delay(400); 50 | Serial3.println(reading); 51 | Serial.println(analogRead(A4)); 52 | } 53 | if(millis()>t+2000){ 54 | if(analogRead(A4)>limit2) 55 | { pump.moveMotor(speedg); 56 | msgflag=1; 57 | //digitalWrite(28,HIGH); 58 | } 59 | else if(analogRead(A4) 7 | #include 8 | #include // Core graphics library 9 | #include // Hardware-specific library 10 | #include 11 | #define buzzer 46 12 | #define TFT_CS 48 13 | #define TFT_RST 47 // you can also connect this to the Arduino reset 14 | // in which case, set this #define pin to 0! 15 | #define TFT_DC 49 16 | 17 | Adafruit_ST7735 lcd = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 18 | 19 | int conti=0; 20 | double first = 0; 21 | double second = 0; 22 | double total = 0; 23 | 24 | char customKey; 25 | const byte ROWS = 4; 26 | const byte COLS = 4; 27 | 28 | char keys[ROWS][COLS] = { 29 | {'1','2','3','+'}, 30 | {'4','5','6','-'}, 31 | {'7','8','9','*'}, 32 | {'C','0','=','/'} 33 | }; 34 | byte rowPins[ROWS] = {11,10,9,8}; //connect to the row pinouts of the keypad 35 | byte colPins[COLS] = {5,4,3,2}; //connect to the column pinouts of the keypad 36 | 37 | //initialize an instance of class NewKeypad 38 | Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); 39 | //*****************scientific buttons****************** 40 | int sine=25; 41 | int cosine=27; 42 | int tangent=23; 43 | int logue=22; 44 | int arcsin=24; 45 | int arccos=26; 46 | int arctan=14; 47 | int root=15; 48 | 49 | //***************************************************** 50 | void setup() 51 | { 52 | pinMode(sine,INPUT); 53 | pinMode(cosine,INPUT); 54 | pinMode(tangent,INPUT); 55 | pinMode(logue,INPUT); 56 | pinMode(arcsin,INPUT); 57 | pinMode(arccos,INPUT); 58 | pinMode(arctan,INPUT); 59 | pinMode(root,INPUT); 60 | pinMode(13,OUTPUT); 61 | 62 | Serial.begin(9600); 63 | 64 | lcd.initR(INITR_BLACKTAB); 65 | lcd.fillScreen(ST7735_BLACK); 66 | lcd.setRotation(1); 67 | lcd.setCursor(0,0); 68 | lcd.setTextColor(ST7735_WHITE,ST7735_BLACK); 69 | lcd.setTextSize(2); 70 | } 71 | void printhistory(double first,double second,char sign){ 72 | lcd.setTextSize(1); 73 | lcd.setCursor(0,100); 74 | lcd.setTextColor(ST7735_YELLOW,ST7735_BLACK); 75 | lcd.print("Previous---------------------------"); 76 | lcd.setCursor(0,110); 77 | lcd.setTextColor(ST7735_CYAN,ST7735_BLACK); 78 | lcd.print(first,4); 79 | lcd.print(" "); 80 | lcd.print(sign); 81 | lcd.print(" "); 82 | lcd.print(second,4); 83 | lcd.setTextColor(ST7735_WHITE,ST7735_BLACK); 84 | lcd.setTextSize(2); 85 | } 86 | 87 | bool isDecimal1=false; 88 | float decimals1=10.0; 89 | bool isDecimal2=false; 90 | float decimals2=10.0; 91 | 92 | void loop() 93 | { 94 | customKey = customKeypad.getKey(); 95 | //******************************sin, cos, tan, logarithm and inverse****************** 96 | if(digitalRead(logue)==HIGH) 97 | { delay(250); 98 | if(digitalRead(logue)==HIGH) 99 | { Serial.println("log 1"); 100 | tone(buzzer,5000,100); 101 | if(first!=0) 102 | first=log(first); 103 | else 104 | first=-999999999999999; 105 | lcd.setCursor(0,0); 106 | lcd.print(first,4); 107 | } 108 | } //log ends 109 | 110 | if(digitalRead(sine)==HIGH) 111 | { delay(250); 112 | if(digitalRead(sine)==HIGH) 113 | { Serial.println("sine 1"); 114 | tone(buzzer,5000,100); 115 | if(first!=0) 116 | first=sin(first); 117 | else 118 | first=0; 119 | lcd.setCursor(0,0); 120 | lcd.print(first,4); 121 | } 122 | } //sine ends 123 | 124 | if(digitalRead(cosine)==HIGH) 125 | { delay(250); 126 | if(digitalRead(cosine)==HIGH) 127 | { Serial.println("cosine 1"); 128 | tone(buzzer,5000,100); 129 | if(first!=0) 130 | first=cos(first); 131 | else 132 | first=1; 133 | lcd.setCursor(0,0); 134 | lcd.print(first,4); 135 | } 136 | } 137 | if(digitalRead(tangent)==HIGH) 138 | { delay(250); 139 | if(digitalRead(tangent)==HIGH) 140 | { Serial.println("tangent 1"); 141 | tone(buzzer,5000,100); 142 | if(first!=0) 143 | first=tan(first); 144 | else 145 | first=0; 146 | lcd.setCursor(0,0); 147 | lcd.print(first,4); 148 | } 149 | } 150 | 151 | if(digitalRead(arcsin)==HIGH) 152 | { delay(250); 153 | if(digitalRead(arcsin)==HIGH) 154 | { Serial.println("asin 1"); 155 | tone(buzzer,5000,100); 156 | if(first!=0) 157 | first=asin(first); 158 | else 159 | first=0; 160 | lcd.setCursor(0,0); 161 | lcd.print(first,4); 162 | } 163 | } //asine ends 164 | 165 | if(digitalRead(arccos)==HIGH) 166 | { delay(250); 167 | if(digitalRead(arccos)==HIGH) 168 | { Serial.println("arccos 1"); 169 | tone(buzzer,5000,100); 170 | if(first!=0) 171 | first=acos(first); 172 | else 173 | first=1.57; 174 | lcd.setCursor(0,0); 175 | lcd.print(first,4); 176 | } 177 | } 178 | if(digitalRead(arctan)==HIGH) 179 | { delay(250); 180 | if(digitalRead(arctan)==HIGH) 181 | { Serial.println("arctan 1"); 182 | tone(buzzer,5000,100); 183 | if(first!=0) 184 | first=atan(first); 185 | else 186 | first=0; 187 | lcd.setCursor(0,0); 188 | lcd.print(first,4); 189 | } 190 | } 191 | 192 | if(digitalRead(root)==HIGH) 193 | { delay(250); 194 | if(digitalRead(root)==HIGH) 195 | { Serial.println("root 1"); 196 | tone(buzzer,5000,100); 197 | if(first!=0) 198 | first=sqrt(first); 199 | else 200 | first=0; 201 | lcd.setCursor(0,0); 202 | lcd.print(first,4); 203 | } 204 | } 205 | //************************sin, cos, tan, logarithm and inverse end************************ 206 | 207 | if(digitalRead(17)==HIGH) 208 | { 209 | delay(250); 210 | if(digitalRead(17)==HIGH) 211 | { tone(buzzer,5000,100); 212 | isDecimal1=true; 213 | } 214 | } 215 | if(customKey!=NO_KEY){ 216 | tone(buzzer,5000,100); 217 | Serial.println(isDecimal1); 218 | switch(customKey) 219 | { 220 | case '0' ... '9': // This keeps collecting the first value until a operator is pressed "+-*/" 221 | if (isDecimal1==false) 222 | { 223 | lcd.setCursor(0,0); 224 | first = first * 10 + (customKey - '0'); 225 | lcd.print(first,4); 226 | } 227 | else 228 | { 229 | lcd.setCursor(0,0); 230 | first=first+(customKey - '0')/decimals1; 231 | decimals1=decimals1*10; 232 | lcd.print(first,4); 233 | } 234 | break; 235 | case '+': 236 | first = (total != 0 ? total : first); 237 | A: 238 | lcd.setCursor(0,20); 239 | lcd.print("+"); 240 | second = SecondNumber(); // get the collected the second number 241 | total = first + second; 242 | lcd.setCursor(0,60); 243 | lcd.setTextColor(ST7735_RED,ST7735_BLACK); 244 | lcd.print("---------------"); 245 | lcd.setCursor(0,80); 246 | lcd.setTextColor(ST7735_GREEN,ST7735_BLACK); 247 | lcd.print(total); 248 | lcd.setTextColor(ST7735_WHITE,ST7735_BLACK); 249 | delay(500); 250 | lcd.fillScreen(ST7735_BLACK); 251 | printhistory(first,second,'+'); 252 | first = total, second = 0; // reset values back to zero for next use 253 | lcd.setCursor(0,0); 254 | lcd.print(first,4); 255 | if(conti==1) 256 | goto A; 257 | else if(conti==2) 258 | goto B; 259 | else if(conti==3) 260 | goto C; 261 | else if(conti==4) 262 | goto D; 263 | total=0; 264 | break; 265 | 266 | case '-': 267 | first = (total != 0 ? total : first); 268 | B: 269 | lcd.setCursor(0,20); 270 | lcd.print("-"); 271 | second = SecondNumber(); 272 | total = first - second; 273 | lcd.setCursor(0,60); 274 | lcd.setTextColor(ST7735_RED,ST7735_BLACK); 275 | lcd.print("---------------"); 276 | lcd.setCursor(0,80); 277 | lcd.setTextColor(ST7735_GREEN,ST7735_BLACK); 278 | lcd.print(total); 279 | lcd.setTextColor(ST7735_WHITE,ST7735_BLACK); 280 | delay(500); 281 | lcd.fillScreen(ST7735_BLACK); 282 | printhistory(first,second,'-'); 283 | first = total, second = 0; // reset values back to zero for next use 284 | lcd.setCursor(0,0); 285 | lcd.print(first,4); 286 | if(conti==1) 287 | goto A; 288 | else if(conti==2) 289 | goto B; 290 | else if(conti==3) 291 | goto C; 292 | else if(conti==4) 293 | goto D; 294 | total=0; 295 | break; 296 | 297 | case '*': 298 | first = (total != 0 ? total : first); 299 | C: 300 | lcd.setCursor(0,20); 301 | lcd.print("*"); 302 | second = SecondNumber(); 303 | total = first * second; 304 | lcd.setCursor(0,60); 305 | lcd.setTextColor(ST7735_RED,ST7735_BLACK); 306 | lcd.print("---------------"); 307 | lcd.setCursor(0,80); 308 | lcd.setTextColor(ST7735_GREEN,ST7735_BLACK); 309 | lcd.print(total); 310 | lcd.setTextColor(ST7735_WHITE,ST7735_BLACK); 311 | delay(500); 312 | lcd.fillScreen(ST7735_BLACK); 313 | printhistory(first,second,'*'); 314 | first = total, second = 0; // reset values back to zero for next use 315 | lcd.setCursor(0,0); 316 | lcd.print(first,4); 317 | if(conti==1) 318 | goto A; 319 | else if(conti==2) 320 | goto B; 321 | else if(conti==3) 322 | goto C; 323 | else if(conti==4) 324 | goto D; 325 | total=0; 326 | break; 327 | 328 | case '/': 329 | first = (total != 0 ? total : first); 330 | D: 331 | lcd.setCursor(0,20); 332 | lcd.print("/"); 333 | second = SecondNumber(); 334 | lcd.setCursor(0,60); 335 | 336 | second == 0 ? lcd.print("Invalid") : total = (float)first / (float)second; 337 | 338 | if(second!=0) 339 | { 340 | lcd.setTextColor(ST7735_RED,ST7735_BLACK); 341 | lcd.print("---------------"); 342 | lcd.setCursor(0,80); 343 | lcd.setTextColor(ST7735_GREEN,ST7735_BLACK); 344 | lcd.print(total); 345 | lcd.setTextColor(ST7735_WHITE,ST7735_BLACK); 346 | delay(500); 347 | lcd.fillScreen(ST7735_BLACK); 348 | printhistory(first,second,'/'); 349 | first = total, second = 0; // reset values back to zero for next use 350 | lcd.setCursor(0,0); 351 | lcd.print(first,4); 352 | if(conti==1) 353 | goto A; 354 | else if(conti==2) 355 | goto B; 356 | else if(conti==3) 357 | goto C; 358 | else if(conti==4) 359 | goto D; 360 | total=0; 361 | } 362 | break; 363 | 364 | case 'C': 365 | total = 0; 366 | lcd.fillScreen(ST7735_BLACK); 367 | first=0; 368 | second=0; 369 | isDecimal1=false; 370 | isDecimal2=false; 371 | decimals1=10; 372 | decimals2=10; 373 | break; 374 | 375 | } 376 | } 377 | } 378 | 379 | double SecondNumber() 380 | { 381 | while( 1 ) 382 | { 383 | customKey = customKeypad.getKey(); 384 | if(digitalRead(17)==HIGH) 385 | { 386 | delay(250); 387 | if(digitalRead(17)==HIGH) 388 | { tone(buzzer,5000,100); 389 | isDecimal2=true; 390 | } 391 | } 392 | if(customKey!=NO_KEY) 393 | { 394 | tone(buzzer,5000,100); 395 | Serial.println(isDecimal2); 396 | } 397 | if(customKey >= '0' && customKey <= '9') 398 | { 399 | if (isDecimal2==false) 400 | { 401 | lcd.setCursor(0,40); 402 | second = second * 10 + (customKey - '0'); 403 | lcd.print(second,4); 404 | } 405 | else 406 | { 407 | lcd.setCursor(0,40); 408 | second=second+(customKey - '0')/decimals2; 409 | decimals2=decimals2*10; 410 | lcd.print(second,4); 411 | } 412 | } 413 | 414 | if(customKey == '=') 415 | { 416 | conti=0; 417 | isDecimal1=false; 418 | isDecimal2=false; 419 | decimals1=10; 420 | decimals2=10; 421 | break; //return second; 422 | 423 | } 424 | else if(customKey == '+') 425 | { conti=1; 426 | break; 427 | } 428 | else if(customKey=='-') 429 | { conti=2; 430 | break; 431 | } 432 | else if(customKey=='*') 433 | { conti=3; 434 | break; 435 | } 436 | else if(customKey=='/') 437 | { conti=4; 438 | break; 439 | } 440 | } 441 | return second; 442 | 443 | } 444 | -------------------------------------------------------------------------------- /simonSaysGame/simonSaysGame.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * This code is tested with evive. Visit http://evive.cc for more information 3 | * Code developed by- Tushar Gupta (tushargupta5197@gmail.com) & Madhukant(kantmadhu956@gmail.com) 4 | * Date developed - 28/6/2016 5 | */ 6 | #include // Core graphics library 7 | #include // Hardware-specific library 8 | #include 9 | 10 | #define TFT_CS 48 11 | #define TFT_RST 47 // you can also connect this to the Arduino reset 12 | // in which case, set this #define pin to 0! 13 | #define TFT_DC 49 14 | 15 | Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 16 | 17 | void setup() { 18 | for(int i=2;i<=6;i++) 19 | pinMode(i,OUTPUT); 20 | Serial.begin(9600); 21 | tft.initR(INITR_BLACKTAB); // intialising the screen 22 | tft.fillScreen(ST7735_BLACK); 23 | tft.setRotation(1); //to set the TFT screen Landscape 24 | tft.setTextWrap(false); 25 | tft.setTextColor(ST7735_WHITE,ST7735_BLACK); 26 | } 27 | bool once=true; 28 | int k=0,arr[5]={0,0,0,0,0}; 29 | int arr1[5]={random(1,6),random(1,6),random(1,6),random(1,6),random(1,6)}; 30 | int a,j=0; 31 | int level=1, deltaTime=500; 32 | void loop() { 33 | //printing on the screen 34 | tft.setTextSize(2); 35 | tft.setCursor(15,15); 36 | tft.print("Simon Says"); 37 | tft.setTextSize(3); 38 | tft.setCursor(15,50); 39 | tft.print("level: "); 40 | tft.print(level); 41 | 42 | if (once==true) 43 | for(int i=0;i<=4;i++) 44 | {digitalWrite(arr1[i]+1,HIGH);delay(deltaTime);digitalWrite(arr1[i]+1,LOW);delay(deltaTime);once=false;} 45 | //changing the pin mode to input 46 | for(int i=2;i<=6;i++) 47 | pinMode(i,INPUT); 48 | 49 | if((digitalRead(2)==HIGH)||(digitalRead(3)==HIGH)||(digitalRead(4)==HIGH)||(digitalRead(5)==HIGH)||(digitalRead(6)==HIGH)) 50 | { 51 | //debouncing the switch 52 | if(digitalRead(2)==HIGH) 53 | //Serial.println("2"); 54 | a=2; 55 | else if(digitalRead(3)==HIGH) 56 | // Serial.println("3"); 57 | a=3; 58 | else if(digitalRead(6)==HIGH) 59 | a=6;//Serial.println("6"); 60 | 61 | else if(digitalRead(4)==HIGH) 62 | a=4;//Serial.println("4"); 63 | 64 | else if(digitalRead(5)==HIGH) 65 | a=5; 66 | 67 | arr[j]=a-1; 68 | } 69 | else a=0; 70 | if(arr[j]!=0&&j<5&&a==0) 71 | { 72 | j++; 73 | } 74 | Serial.println(j); 75 | 76 | if(j==5) 77 | { 78 | for(int g=2;g<=6;g++) 79 | { 80 | pinMode(g,OUTPUT); 81 | } 82 | for(int i=0;i<5;i++) 83 | { 84 | Serial.print(arr[i]); 85 | Serial.print(" "); 86 | } 87 | Serial.println(); 88 | for(int i=0;i<5;i++) 89 | { 90 | Serial.print(arr1[i]); 91 | Serial.print(" "); 92 | } 93 | Serial.println(); 94 | for(k=0;k<5;k++) 95 | { 96 | if( arr[k]==arr1[k]) 97 | continue; 98 | else break; 99 | } 100 | 101 | // level completed next level 102 | 103 | if(k==5) 104 | { 105 | for(int g=2;g<=6;g++) 106 | { 107 | digitalWrite(g,HIGH); 108 | delay (100); 109 | digitalWrite(g,LOW); 110 | } 111 | for(int i=2;i<=6;i++) 112 | pinMode(i,OUTPUT); 113 | 114 | once=true;; 115 | k=0; 116 | for(int i=0;i<5;i++) 117 | { 118 | arr[i]=0; 119 | arr1[i]=random(1,6); 120 | } 121 | a=0;j=0; 122 | level++; 123 | deltaTime=deltaTime-50; 124 | } 125 | else 126 | { 127 | for(int g=2;g<=6;g++) 128 | { 129 | digitalWrite(g,HIGH); 130 | } 131 | tft.fillScreen(ST7735_BLACK); 132 | tft.setCursor(5,50); 133 | tft.print("Game Over"); 134 | 135 | delay(3000); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /skateboard/motor/motor.cpp: -------------------------------------------------------------------------------- 1 | /*library tested 30 NOVEMBER 2 | Made by Deep Goel and Kartik Gupta 3 | */ 4 | 5 | #include 6 | //#include 7 | #include 8 | Motor::Motor() //constructor 9 | { 10 | attachMotor(-1,-1,-1); 11 | } 12 | 13 | Motor::Motor(int Dir1, int Dir2, int Pwm ) // parametrised constructor 14 | { 15 | attachMotor(Dir1,Dir2,Pwm); 16 | } 17 | 18 | void Motor::attachMotor(int Dir1,int Dir2,int Pwm) 19 | { 20 | pwm_pin= Pwm; 21 | dir1_pin = Dir1; 22 | dir2_pin = Dir2; 23 | if(dir1!=-1 && dir2!=-1 && pwm_pin!=-1) 24 | { 25 | pinMode(pwm_pin,OUTPUT); 26 | pinMode(dir1_pin,OUTPUT); 27 | pinMode(dir2_pin,OUTPUT); 28 | } 29 | pwm = 0; 30 | speed = 0; 31 | mean_speed = 255; 32 | //lockMotor(); //Lock the Motor initially 33 | damping=10; 34 | } 35 | 36 | 37 | void Motor::moveMotor(int Pwm) //+ve for CW and -ve for CCW. 38 | { 39 | 40 | if(Pwm>=0) 41 | { 42 | digitalWrite(dir1_pin,HIGH); 43 | digitalWrite(dir2_pin,LOW); 44 | } 45 | else 46 | { 47 | digitalWrite(dir1_pin,LOW); 48 | digitalWrite(dir2_pin,HIGH); 49 | } 50 | changePWM(Pwm); 51 | // Serial.println("PWM="); 52 | // Serial.print(Pwm); 53 | } 54 | 55 | void Motor::moveMotor(int Dir1,int Dir2,int Pwm) 56 | { 57 | if(Dir1==1 && Dir2==0) 58 | moveMotor(Pwm); 59 | if(Dir1==0 && Dir2==1) 60 | moveMotor(-Pwm); 61 | } 62 | 63 | void Motor::stopMotor() //By default stop motor will lock motor 64 | { 65 | lockMotor(); 66 | } 67 | 68 | void Motor::lockMotor() 69 | { 70 | digitalWrite(dir1_pin,HIGH); //case of motor lock 71 | digitalWrite(dir2_pin,HIGH); 72 | analogWrite(pwm_pin,255); 73 | pwm=0; 74 | } 75 | 76 | void Motor::freeMotor() 77 | { 78 | digitalWrite(dir1_pin,LOW); //case of motor free 79 | digitalWrite(dir2_pin,LOW); 80 | analogWrite(pwm_pin,0); 81 | pwm=0; 82 | } 83 | 84 | void Motor::setMeanSpeed(int Speed) //Sets the meanspeed with which motor moves when speed=100% 85 | { 86 | mean_speed=Speed; 87 | } 88 | 89 | void Motor::setMotorSpeed(int Speed) //+ve for CW and -ve for CCW. Speed in percentage of meanspeed 90 | { 91 | if(Speed>100) 92 | Speed=100; 93 | if(Speed<-100) 94 | Speed=-100; 95 | speed=Speed; 96 | 97 | moveMotor(Speed*mean_speed/100); 98 | } 99 | 100 | void Motor::setMotorSpeed(int Dir1,int Dir2,int Speed) 101 | { 102 | if(Speed>100) 103 | Speed=100; 104 | if(Speed<-100) 105 | Speed=-100; 106 | speed=Speed; 107 | moveMotor(Dir1,Dir2,Speed*mean_speed/100); 108 | } 109 | 110 | void Motor::changePWM(int Pwm) //Just to change the PWM 111 | { 112 | pwm = Pwm>255 ? 255 : (Pwm < -255 ? -255 :Pwm); 113 | analogWrite(pwm_pin,abs(pwm)); 114 | } 115 | 116 | void Motor::changeSpeed(int Speed) //Just to change the speed (In percentage) 117 | { 118 | if(Speed>100) 119 | Speed=100; 120 | if(Speed<-100) 121 | Speed=-100; 122 | speed=Speed; 123 | changePWM(Speed*mean_speed/100); 124 | } 125 | 126 | int Motor::getDirection() 127 | { 128 | dir1=digitalRead(dir1_pin); 129 | dir2=digitalRead(dir2_pin); 130 | if (dir1==dir2) 131 | return 0; 132 | else 133 | return((dir1>dir2)?1:-1); 134 | } 135 | 136 | int Motor::isFree() 137 | { 138 | return (getDirection()==0 && dir1==0); 139 | } 140 | 141 | int Motor::isLocked() 142 | { 143 | return (getDirection()==0 && dir1==1); 144 | } 145 | 146 | int Motor::getSpeed() 147 | { 148 | return(pwm*100/mean_speed); 149 | } 150 | 151 | int Motor::getPWM() 152 | { 153 | return pwm; 154 | } 155 | 156 | void Motor::startSmoothly(int Speed) 157 | { 158 | if(Speed>100) 159 | Speed=100; 160 | if(Speed<-100) 161 | Speed=-100; 162 | int i; 163 | if(Speed>=0) 164 | { 165 | digitalWrite(dir1_pin,HIGH); 166 | digitalWrite(dir2_pin,LOW); 167 | } 168 | else 169 | { 170 | digitalWrite(dir1_pin,LOW); 171 | digitalWrite(dir2_pin,HIGH); 172 | } 173 | for(i=0;i<=Speed;i=i+COUNT_CONST) 174 | { 175 | changeSpeed(i); 176 | delay(COUNT_CONST*damping); 177 | speed=i; 178 | pwm=speed*mean_speed/100; 179 | } 180 | } 181 | void Motor::stopSmoothly() 182 | { int i; 183 | speed=getSpeed(); 184 | for(i=speed;i>=0;i=i-COUNT_CONST) 185 | { 186 | changeSpeed(i); 187 | delay(COUNT_CONST*damping); 188 | speed=i; 189 | pwm=speed*mean_speed/100; 190 | } 191 | lockMotor(); 192 | } 193 | -------------------------------------------------------------------------------- /skateboard/motor/motor.h: -------------------------------------------------------------------------------- 1 | /*library tested 30 NOVEMBER 2 | Made by Deep Goel and Kartik Gupta 3 | */ 4 | #ifndef MOTOR_H 5 | #define MOTOR_H 6 | // 7 | //(imp) motor will be considered cw if dir1 is HIGH and DIR2 is LOW 8 | // 9 | 10 | 11 | #ifndef COUNT_CONST 12 | #define COUNT_CONST 3 13 | 14 | #endif //for COUNT_CONST 15 | class Motor 16 | { 17 | // private: 18 | 19 | 20 | public: 21 | // Variables 22 | 23 | int dir1_pin; //stores pin no of direction1 24 | int dir2_pin; //stores pin no of direction2 25 | int pwm_pin; //stores pin no of pwm pin 26 | int dir1; //stores value of DIR1PIN as 1 or 0 27 | int dir2; //stores value of DIR2PIN as 1 or 0 28 | int pwm; //pwm: Stores the pwm value given to the motor 29 | int mean_speed; //mean_speed : The value to which motor moves when speed=100% 30 | float speed; //speed : Speed of the motor in percentage of meanspeed 31 | int damping; //to be changed later by trial 32 | 33 | // Functions 34 | public: 35 | Motor(); //constructor 36 | Motor(int Dir1,int Dir2,int Pwm); //constructor with attachments of pins 37 | void attachMotor(int Dir1,int Dir2,int Pwm); //attachments of pins 38 | void moveMotor(int Pwm); //+ve for CW and -ve for CCW. 39 | void moveMotor(int Dir1,int Dir2,int Pwm); // dir1 and dir2 can be 1 or 0,pwm can only be +ve for CW 40 | void stopMotor(); //By default stop motor will lock motor 41 | void lockMotor(); //To lock the motor 42 | void freeMotor(); //Free the motor 43 | void setMeanSpeed(int Speed); //Sets the meanspeed with which motor moves when speed=100% 44 | void setMotorSpeed(int Speed); //+ve for CW and -ve for CCW. Speed in percentage of meanspeed 45 | void setMotorSpeed(int Dir1,int Dir2,int Speed); // dir1 and dir2 can be 1 or 0 46 | void changePWM(int Pwm); //Just to change the PWM in whatever direction the motor was moving 47 | void changeSpeed(int Speed); //Just to change the speed (In percentage) not the direction 48 | int getDirection(); //+1 for cw and -1 for ccw and 0 for free or locked 49 | int isFree(); //+1 for free and 0 for not free 50 | int isLocked(); //+1 for locked and 0 for not locked 51 | int getSpeed(); // returns speed in % of mean speed 52 | int getPWM(); // returns +ve for CW and -ve for CCW. 53 | void startSmoothly(int Speed); //+ve for CW and -ve for CCW. 54 | void stopSmoothly(); 55 | }; 56 | #endif 57 | -------------------------------------------------------------------------------- /skateboard/skateboard/skateboard.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Developed by - Madhukant and Tushar Gupta 3 | * Proximity sensor code developed by Dhrupal R Shah 4 | * Email id's :- kantmadhu956@gmail.com or contact@evive.cc 5 | * Dated: August 22, 2016 6 | * 7 | * Notes: Tested with evive, HC-05 as Bluetooth module 8 | * Android App: Arduino Bluetooth Controller 9 | * https://play.google.com/store/apps/details?id=eu.jahnestacado.arduinorc&hl=en 10 | * Set the following values for keys in RC controller menu in App: 11 | * * Up = "1" start or increase speed 12 | * * Down = "3" decrease speed 13 | * * Right = "f" emergency stop 14 | * * Left = "0" for start smoothly 15 | * * Trianlge = "l" for starting lights ro increasing brightness of lights //letter L in small letters 16 | * * Cross = "o" for decreasing brightness of lights 17 | */ 18 | 19 | //Motor.h library can be downloaded from https://github.com/evivetoolkit/eviveProjects/tree/master/skateboard/motor 20 | #include 21 | // include the SPI library: 22 | #include 23 | 24 | //Since the output of proximity is 0 or 12V, evive's sensing channel at ProbeV (has range of -30V to +30V) is used 25 | int SPI_ADC_SS = 35; // SPI ADC SS 26 | int ADC_RDY = 32; // ADC Ready pin 27 | #define ADC_SPIMaxSpeed 5600000 28 | #define ADC_SPIMode SPI_MODE3 29 | #define ADC_SPIDataOrder MSBFIRST 30 | #define ADE791X_REG_V1WV 0x01 /* Instantaneous value of Voltage V1 */ 31 | #define ADE791X_MUL_V1WV 0.006485 32 | #define ADE791X_OFFSET_V1WV 362760 33 | #define ADE791X_READ 0x04 34 | 35 | SPISettings ADCSetting(ADC_SPIMaxSpeed,ADC_SPIDataOrder,ADC_SPIMode); 36 | 37 | Motor mymotor(28,29,44); 38 | Motor lights(30,31,45); 39 | void setup() { 40 | ade791x_init(); 41 | delay(100); 42 | Serial3.begin(9600); 43 | mymotor.stopMotor(); 44 | Serial.begin(9600); 45 | } 46 | int speedMotor=-90; 47 | int brightness=0; 48 | String inputString=""; 49 | int junk; 50 | 51 | void ade791x_init(void) 52 | { 53 | pinMode(SPI_ADC_SS, OUTPUT); 54 | pinMode(ADC_RDY, INPUT); 55 | // take the SS pin high to de-select the chip: 56 | digitalWrite(SPI_ADC_SS, HIGH); 57 | // initialize SPI: 58 | SPI.begin(); 59 | } 60 | 61 | 62 | /////////////////////////////////////////////////////////////////////////////// 63 | // function name: ade791x_read_v1() 64 | // inputs: none 65 | // outputs: 4 byte / signed long value read from ADC V1WV register 66 | // Description: function that reads ADE791x ADC V1WV register over SPI 67 | // interface. 68 | /////////////////////////////////////////////////////////////////////////////// 69 | 70 | long ade791x_read_v1(void) 71 | { 72 | unsigned char addr = ADE791X_REG_V1WV; 73 | long value = 0; // stores value to return 74 | long tempValue1 = 0, tempValue2 = 0 , tempValue3 = 0; 75 | unsigned char opcode; // stores opcode 76 | 77 | addr = addr << 3; // left shift address by 3 bits 78 | opcode = (addr | ADE791X_READ); // forms opcode byte 79 | // Serial.print ("opcode: "); // for debug only 80 | // Serial.println(opcode, BIN); // for debug only 81 | 82 | SPI.beginTransaction(ADCSetting); 83 | // take the SS pin low to select the chip: 84 | // digitalWrite(SPI_ADC_SS, LOW); // bring SS2 pin low 85 | PORTC &= ~_BV(PC2); 86 | SPI.transfer(opcode); // send out opcode 87 | // value = SPI.transfer(0xFF) * 0x10000; // read MS Byte 88 | //// tempValue1=value; 89 | // value |= SPI.transfer(0xFF) * 0x100; // read mid Byte 90 | //// tempValue2=value; 91 | // value |= SPI.transfer(0xFF); // LS Byte 92 | 93 | tempValue1 = SPI.transfer(0xFF); // read MS Byte 94 | // tempValue1=value; 95 | tempValue2 = SPI.transfer(0xFF); // read mid Byte 96 | // tempValue2=value; 97 | tempValue3 = SPI.transfer(0xFF); // LS Byte 98 | 99 | // take the SS pin high 100 | // 101 | //to de-select the chip: 102 | //digitalWrite(SPI_ADC_SS, HIGH); 103 | PORTC |= _BV(PC2); 104 | 105 | SPI.endTransaction(); 106 | 107 | tempValue1 = tempValue1 * 0x10000; 108 | tempValue2 = tempValue1 | tempValue2 * 0x100; 109 | value = tempValue2 | tempValue3; 110 | 111 | value = value <<8; // sign extends value to 32 bit 112 | value = value / 0x100; // converts back value to 24 bit but now sign extended 113 | value = (value - 362760.0)*0.006485; //ADE791X_MUL_V1WV; 114 | 115 | #ifdef __DEBUG__ 116 | // Serial.print ("V1: "); 117 | // Serial.println (value); 118 | #endif 119 | return value; 120 | } 121 | 122 | void loop() { 123 | //if value is greater than 6000, stop skateboard. 124 | int proxyVal = ade791x_read_v1 (); 125 | if(proxyVal>3000) 126 | { 127 | mymotor.stopMotor(); 128 | } 129 | Serial.println(proxyVal); 130 | if(Serial3.available()){ 131 | while(Serial3.available()) 132 | { 133 | char inChar = (char)Serial3.read(); //read the input 134 | inputString += inChar; //make a string of the characters coming onSerial3 135 | } 136 | Serial3.println(inputString); 137 | Serial3.println(123); 138 | while (Serial3.available() > 0) 139 | { junk =Serial3.read() ; } // clear the serial buffer 140 | 141 | if(inputString == "0"){ //in case of 'a' turn the LED on 142 | mymotor.startSmoothly(speedMotor); 143 | } 144 | else if(inputString=="9") 145 | { 146 | lights.startSmoothly(brightness); 147 | } 148 | else if(inputString=="1") 149 | { 150 | if(speedMotor<225) 151 | mymotor.moveMotor(speedMotor=speedMotor+30); 152 | } 153 | else if(inputString=="3"){ 154 | if(speedMotor>-225) 155 | mymotor.moveMotor(speedMotor=speedMotor-30); 156 | } 157 | else if(inputString=="l"){ 158 | 159 | lights.moveMotor(brightness=brightness+60); 160 | } 161 | else if(inputString=="o"){ 162 | if(brightness>-195) 163 | lights.moveMotor(brightness=brightness-60); 164 | } 165 | else if(inputString=="f"){ 166 | mymotor.stopMotor(); 167 | } 168 | 169 | inputString = ""; 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/Keypad.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file Keypad.cpp 4 | || @version 3.1 5 | || @author Mark Stanley, Alexander Brevig 6 | || @contact mstanley@technologist.com, alexanderbrevig@gmail.com 7 | || 8 | || @description 9 | || | This library provides a simple interface for using matrix 10 | || | keypads. It supports multiple keypresses while maintaining 11 | || | backwards compatibility with the old single key library. 12 | || | It also supports user selectable pins and definable keymaps. 13 | || # 14 | || 15 | || @license 16 | || | This library is free software; you can redistribute it and/or 17 | || | modify it under the terms of the GNU Lesser General Public 18 | || | License as published by the Free Software Foundation; version 19 | || | 2.1 of the License. 20 | || | 21 | || | This library is distributed in the hope that it will be useful, 22 | || | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | || | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 | || | Lesser General Public License for more details. 25 | || | 26 | || | You should have received a copy of the GNU Lesser General Public 27 | || | License along with this library; if not, write to the Free Software 28 | || | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 29 | || # 30 | || 31 | */ 32 | #include 33 | 34 | // <> Allows custom keymap, pin configuration, and keypad sizes. 35 | Keypad::Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols) { 36 | rowPins = row; 37 | columnPins = col; 38 | sizeKpd.rows = numRows; 39 | sizeKpd.columns = numCols; 40 | 41 | begin(userKeymap); 42 | 43 | setDebounceTime(10); 44 | setHoldTime(500); 45 | keypadEventListener = 0; 46 | 47 | startTime = 0; 48 | single_key = false; 49 | } 50 | 51 | // Let the user define a keymap - assume the same row/column count as defined in constructor 52 | void Keypad::begin(char *userKeymap) { 53 | keymap = userKeymap; 54 | } 55 | 56 | // Returns a single key only. Retained for backwards compatibility. 57 | char Keypad::getKey() { 58 | single_key = true; 59 | 60 | if (getKeys() && key[0].stateChanged && (key[0].kstate==PRESSED)) 61 | return key[0].kchar; 62 | 63 | single_key = false; 64 | 65 | return NO_KEY; 66 | } 67 | 68 | // Populate the key list. 69 | bool Keypad::getKeys() { 70 | bool keyActivity = false; 71 | 72 | // Limit how often the keypad is scanned. This makes the loop() run 10 times as fast. 73 | if ( (millis()-startTime)>debounceTime ) { 74 | scanKeys(); 75 | keyActivity = updateList(); 76 | startTime = millis(); 77 | } 78 | 79 | return keyActivity; 80 | } 81 | 82 | // Private : Hardware scan 83 | void Keypad::scanKeys() { 84 | // Re-intialize the row pins. Allows sharing these pins with other hardware. 85 | for (byte r=0; r -1) { 125 | nextKeyState(idx, button); 126 | } 127 | // Key is NOT on the list so add it. 128 | if ((idx == -1) && button) { 129 | for (byte i=0; iholdTime) // Waiting for a key HOLD... 163 | transitionTo (idx, HOLD); 164 | else if (button==OPEN) // or for a key to be RELEASED. 165 | transitionTo (idx, RELEASED); 166 | break; 167 | case HOLD: 168 | if (button==OPEN) 169 | transitionTo (idx, RELEASED); 170 | break; 171 | case RELEASED: 172 | transitionTo (idx, IDLE); 173 | break; 174 | } 175 | } 176 | 177 | // New in 2.1 178 | bool Keypad::isPressed(char keyChar) { 179 | for (byte i=0; i= 100 40 | #include "Arduino.h" 41 | #else 42 | #include "WProgram.h" 43 | #endif 44 | 45 | // bperrybap - Thanks for a well reasoned argument and the following macro(s). 46 | // See http://arduino.cc/forum/index.php/topic,142041.msg1069480.html#msg1069480 47 | #ifndef INPUT_PULLUP 48 | #warning "Using pinMode() INPUT_PULLUP AVR emulation" 49 | #define INPUT_PULLUP 0x2 50 | #define pinMode(_pin, _mode) _mypinMode(_pin, _mode) 51 | #define _mypinMode(_pin, _mode) \ 52 | do { \ 53 | if(_mode == INPUT_PULLUP) \ 54 | pinMode(_pin, INPUT); \ 55 | digitalWrite(_pin, 1); \ 56 | if(_mode != INPUT_PULLUP) \ 57 | pinMode(_pin, _mode); \ 58 | }while(0) 59 | #endif 60 | 61 | 62 | #define OPEN LOW 63 | #define CLOSED HIGH 64 | 65 | typedef char KeypadEvent; 66 | typedef unsigned int uint; 67 | typedef unsigned long ulong; 68 | 69 | // Made changes according to this post http://arduino.cc/forum/index.php?topic=58337.0 70 | // by Nick Gammon. Thanks for the input Nick. It actually saved 78 bytes for me. :) 71 | typedef struct { 72 | byte rows; 73 | byte columns; 74 | } KeypadSize; 75 | 76 | #define LIST_MAX 10 // Max number of keys on the active list. 77 | #define MAPSIZE 10 // MAPSIZE is the number of rows (times 16 columns) 78 | #define makeKeymap(x) ((char*)x) 79 | 80 | 81 | //class Keypad : public Key, public HAL_obj { 82 | class Keypad : public Key { 83 | public: 84 | 85 | Keypad(char *userKeymap, byte *row, byte *col, byte numRows, byte numCols); 86 | 87 | virtual void pin_mode(byte pinNum, byte mode) { pinMode(pinNum, mode); } 88 | virtual void pin_write(byte pinNum, boolean level) { digitalWrite(pinNum, level); } 89 | virtual int pin_read(byte pinNum) { return digitalRead(pinNum); } 90 | 91 | uint bitMap[MAPSIZE]; // 10 row x 16 column array of bits. Except Due which has 32 columns. 92 | Key key[LIST_MAX]; 93 | unsigned long holdTimer; 94 | 95 | char getKey(); 96 | bool getKeys(); 97 | KeyState getState(); 98 | void begin(char *userKeymap); 99 | bool isPressed(char keyChar); 100 | void setDebounceTime(uint); 101 | void setHoldTime(uint); 102 | void addEventListener(void (*listener)(char)); 103 | int findInList(char keyChar); 104 | int findInList(int keyCode); 105 | char waitForKey(); 106 | bool keyStateChanged(); 107 | byte numKeys(); 108 | 109 | private: 110 | unsigned long startTime; 111 | char *keymap; 112 | byte *rowPins; 113 | byte *columnPins; 114 | KeypadSize sizeKpd; 115 | uint debounceTime; 116 | uint holdTime; 117 | bool single_key; 118 | 119 | void scanKeys(); 120 | bool updateList(); 121 | void nextKeyState(byte n, boolean button); 122 | void transitionTo(byte n, KeyState nextState); 123 | void (*keypadEventListener)(char); 124 | }; 125 | 126 | #endif 127 | 128 | /* 129 | || @changelog 130 | || | 3.1 2013-01-15 - Mark Stanley : Fixed missing RELEASED & IDLE status when using a single key. 131 | || | 3.0 2012-07-12 - Mark Stanley : Made library multi-keypress by default. (Backwards compatible) 132 | || | 3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C 133 | || | 3.0 2012-07-12 - Stanley & Young : Removed static variables. Fix for multiple keypad objects. 134 | || | 3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins when pressing multiple keys. 135 | || | 2.0 2011-12-29 - Mark Stanley : Added waitForKey(). 136 | || | 2.0 2011-12-23 - Mark Stanley : Added the public function keyStateChanged(). 137 | || | 2.0 2011-12-23 - Mark Stanley : Added the private function scanKeys(). 138 | || | 2.0 2011-12-23 - Mark Stanley : Moved the Finite State Machine into the function getKeyState(). 139 | || | 2.0 2011-12-23 - Mark Stanley : Removed the member variable lastUdate. Not needed after rewrite. 140 | || | 1.8 2011-11-21 - Mark Stanley : Added test to determine which header file to compile, 141 | || | WProgram.h or Arduino.h. 142 | || | 1.8 2009-07-08 - Alexander Brevig : No longer uses arrays 143 | || | 1.7 2009-06-18 - Alexander Brevig : This library is a Finite State Machine every time a state changes 144 | || | the keypadEventListener will trigger, if set 145 | || | 1.7 2009-06-18 - Alexander Brevig : Added setDebounceTime setHoldTime specifies the amount of 146 | || | microseconds before a HOLD state triggers 147 | || | 1.7 2009-06-18 - Alexander Brevig : Added transitionTo 148 | || | 1.6 2009-06-15 - Alexander Brevig : Added getState() and state variable 149 | || | 1.5 2009-05-19 - Alexander Brevig : Added setHoldTime() 150 | || | 1.4 2009-05-15 - Alexander Brevig : Added addEventListener 151 | || | 1.3 2009-05-12 - Alexander Brevig : Added lastUdate, in order to do simple debouncing 152 | || | 1.2 2009-05-09 - Alexander Brevig : Changed getKey() 153 | || | 1.1 2009-04-28 - Alexander Brevig : Modified API, and made variables private 154 | || | 1.0 2007-XX-XX - Mark Stanley : Initial Release 155 | || # 156 | */ 157 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/examples/CustomKeypad/CustomKeypad.ino: -------------------------------------------------------------------------------- 1 | /* @file CustomKeypad.pde 2 | || @version 1.0 3 | || @author Alexander Brevig 4 | || @contact alexanderbrevig@gmail.com 5 | || 6 | || @description 7 | || | Demonstrates changing the keypad size and key values. 8 | || # 9 | */ 10 | #include 11 | 12 | const byte ROWS = 4; //four rows 13 | const byte COLS = 4; //four columns 14 | //define the cymbols on the buttons of the keypads 15 | char hexaKeys[ROWS][COLS] = { 16 | {'0','1','2','3'}, 17 | {'4','5','6','7'}, 18 | {'8','9','A','B'}, 19 | {'C','D','E','F'} 20 | }; 21 | byte rowPins[ROWS] = {3, 2, 1, 0}; //connect to the row pinouts of the keypad 22 | byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad 23 | 24 | //initialize an instance of class NewKeypad 25 | Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); 26 | 27 | void setup(){ 28 | Serial.begin(9600); 29 | } 30 | 31 | void loop(){ 32 | char customKey = customKeypad.getKey(); 33 | 34 | if (customKey){ 35 | Serial.println(customKey); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/examples/DynamicKeypad/DynamicKeypad.ino: -------------------------------------------------------------------------------- 1 | /* @file DynamicKeypad.pde 2 | || @version 1.2 3 | || @author Mark Stanley 4 | || @contact mstanley@technologist.com 5 | || 6 | || 07/11/12 - Re-modified (from DynamicKeypadJoe2) to use direct-connect kpds 7 | || 02/28/12 - Modified to use I2C i/o G. D. (Joe) Young 8 | || 9 | || 10 | || @dificulty: Intermediate 11 | || 12 | || @description 13 | || | This is a demonstration of keypadEvents. It's used to switch between keymaps 14 | || | while using only one keypad. The main concepts being demonstrated are: 15 | || | 16 | || | Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding. 17 | || | How to use setHoldTime() and why. 18 | || | Making more than one thing happen with the same key. 19 | || | Assigning and changing keymaps on the fly. 20 | || | 21 | || | Another useful feature is also included with this demonstration although 22 | || | it's not really one of the concepts that I wanted to show you. If you look 23 | || | at the code in the PRESSED event you will see that the first section of that 24 | || | code is used to scroll through three different letters on each key. For 25 | || | example, pressing the '2' key will step through the letters 'd', 'e' and 'f'. 26 | || | 27 | || | 28 | || | Using the keypad events, PRESSED, HOLD and RELEASED to simplify coding 29 | || | Very simply, the PRESSED event occurs imediately upon detecting a pressed 30 | || | key and will not happen again until after a RELEASED event. When the HOLD 31 | || | event fires it always falls between PRESSED and RELEASED. However, it will 32 | || | only occur if a key has been pressed for longer than the setHoldTime() interval. 33 | || | 34 | || | How to use setHoldTime() and why 35 | || | Take a look at keypad.setHoldTime(500) in the code. It is used to set the 36 | || | time delay between a PRESSED event and the start of a HOLD event. The value 37 | || | 500 is in milliseconds (mS) and is equivalent to half a second. After pressing 38 | || | a key for 500mS the HOLD event will fire and any code contained therein will be 39 | || | executed. This event will stay active for as long as you hold the key except 40 | || | in the case of bug #1 listed above. 41 | || | 42 | || | Making more than one thing happen with the same key. 43 | || | If you look under the PRESSED event (case PRESSED:) you will see that the '#' 44 | || | is used to print a new line, Serial.println(). But take a look at the first 45 | || | half of the HOLD event and you will see the same key being used to switch back 46 | || | and forth between the letter and number keymaps that were created with alphaKeys[4][5] 47 | || | and numberKeys[4][5] respectively. 48 | || | 49 | || | Assigning and changing keymaps on the fly 50 | || | You will see that the '#' key has been designated to perform two different functions 51 | || | depending on how long you hold it down. If you press the '#' key for less than the 52 | || | setHoldTime() then it will print a new line. However, if you hold if for longer 53 | || | than that it will switch back and forth between numbers and letters. You can see the 54 | || | keymap changes in the HOLD event. 55 | || | 56 | || | 57 | || | In addition... 58 | || | You might notice a couple of things that you won't find in the Arduino language 59 | || | reference. The first would be #include . This is a standard library from 60 | || | the C programming language and though I don't normally demonstrate these types of 61 | || | things from outside the Arduino language reference I felt that its use here was 62 | || | justified by the simplicity that it brings to this sketch. 63 | || | That simplicity is provided by the two calls to isalpha(key) and isdigit(key). 64 | || | The first one is used to decide if the key that was pressed is any letter from a-z 65 | || | or A-Z and the second one decides if the key is any number from 0-9. The return 66 | || | value from these two functions is either a zero or some positive number greater 67 | || | than zero. This makes it very simple to test a key and see if it is a number or 68 | || | a letter. So when you see the following: 69 | || | 70 | || | if (isalpha(key)) // this tests to see if your key was a letter 71 | || | 72 | || | And the following may be more familiar to some but it is equivalent: 73 | || | 74 | || | if (isalpha(key) != 0) // this tests to see if your key was a letter 75 | || | 76 | || | And Finally... 77 | || | To better understand how the event handler affects your code you will need to remember 78 | || | that it gets called only when you press, hold or release a key. However, once a key 79 | || | is pressed or held then the event handler gets called at the full speed of the loop(). 80 | || | 81 | || # 82 | */ 83 | #include 84 | #include 85 | 86 | const byte ROWS = 4; //four rows 87 | const byte COLS = 3; //three columns 88 | // Define the keymaps. The blank spot (lower left) is the space character. 89 | char alphaKeys[ROWS][COLS] = { 90 | { 'a','d','g' }, 91 | { 'j','m','p' }, 92 | { 's','v','y' }, 93 | { ' ','.','#' } 94 | }; 95 | 96 | char numberKeys[ROWS][COLS] = { 97 | { '1','2','3' }, 98 | { '4','5','6' }, 99 | { '7','8','9' }, 100 | { ' ','0','#' } 101 | }; 102 | 103 | boolean alpha = false; // Start with the numeric keypad. 104 | 105 | byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 106 | byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad 107 | 108 | // Create two new keypads, one is a number pad and the other is a letter pad. 109 | Keypad numpad( makeKeymap(numberKeys), rowPins, colPins, sizeof(rowPins), sizeof(colPins) ); 110 | Keypad ltrpad( makeKeymap(alphaKeys), rowPins, colPins, sizeof(rowPins), sizeof(colPins) ); 111 | 112 | 113 | unsigned long startTime; 114 | const byte ledPin = 13; // Use the LED on pin 13. 115 | 116 | void setup() { 117 | Serial.begin(9600); 118 | pinMode(ledPin, OUTPUT); 119 | digitalWrite(ledPin, LOW); // Turns the LED on. 120 | ltrpad.begin( makeKeymap(alphaKeys) ); 121 | numpad.begin( makeKeymap(numberKeys) ); 122 | ltrpad.addEventListener(keypadEvent_ltr); // Add an event listener. 123 | ltrpad.setHoldTime(500); // Default is 1000mS 124 | numpad.addEventListener(keypadEvent_num); // Add an event listener. 125 | numpad.setHoldTime(500); // Default is 1000mS 126 | } 127 | 128 | char key; 129 | 130 | void loop() { 131 | 132 | if( alpha ) 133 | key = ltrpad.getKey( ); 134 | else 135 | key = numpad.getKey( ); 136 | 137 | if (alpha && millis()-startTime>100) { // Flash the LED if we are using the letter keymap. 138 | digitalWrite(ledPin,!digitalRead(ledPin)); 139 | startTime = millis(); 140 | } 141 | } 142 | 143 | static char virtKey = NO_KEY; // Stores the last virtual key press. (Alpha keys only) 144 | static char physKey = NO_KEY; // Stores the last physical key press. (Alpha keys only) 145 | static char buildStr[12]; 146 | static byte buildCount; 147 | static byte pressCount; 148 | 149 | static byte kpadState; 150 | 151 | // Take care of some special events. 152 | 153 | void keypadEvent_ltr(KeypadEvent key) { 154 | // in here when in alpha mode. 155 | kpadState = ltrpad.getState( ); 156 | swOnState( key ); 157 | } // end ltrs keypad events 158 | 159 | void keypadEvent_num( KeypadEvent key ) { 160 | // in here when using number keypad 161 | kpadState = numpad.getState( ); 162 | swOnState( key ); 163 | } // end numbers keypad events 164 | 165 | void swOnState( char key ) { 166 | switch( kpadState ) { 167 | case PRESSED: 168 | if (isalpha(key)) { // This is a letter key so we're using the letter keymap. 169 | if (physKey != key) { // New key so start with the first of 3 characters. 170 | pressCount = 0; 171 | virtKey = key; 172 | physKey = key; 173 | } 174 | else { // Pressed the same key again... 175 | virtKey++; // so select the next character on that key. 176 | pressCount++; // Tracks how many times we press the same key. 177 | } 178 | if (pressCount > 2) { // Last character reached so cycle back to start. 179 | pressCount = 0; 180 | virtKey = key; 181 | } 182 | Serial.print(virtKey); // Used for testing. 183 | } 184 | if (isdigit(key) || key == ' ' || key == '.') 185 | Serial.print(key); 186 | if (key == '#') 187 | Serial.println(); 188 | break; 189 | 190 | case HOLD: 191 | if (key == '#') { // Toggle between keymaps. 192 | if (alpha == true) { // We are currently using a keymap with letters 193 | alpha = false; // Now we want a keymap with numbers. 194 | digitalWrite(ledPin, LOW); 195 | } 196 | else { // We are currently using a keymap with numbers 197 | alpha = true; // Now we want a keymap with letters. 198 | } 199 | } 200 | else { // Some key other than '#' was pressed. 201 | buildStr[buildCount++] = (isalpha(key)) ? virtKey : key; 202 | buildStr[buildCount] = '\0'; 203 | Serial.println(); 204 | Serial.println(buildStr); 205 | } 206 | break; 207 | 208 | case RELEASED: 209 | if (buildCount >= sizeof(buildStr)) buildCount = 0; // Our string is full. Start fresh. 210 | break; 211 | } // end switch-case 212 | }// end switch on state function 213 | 214 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/examples/EventKeypad/EventKeypad.ino: -------------------------------------------------------------------------------- 1 | /* @file EventSerialKeypad.pde 2 | || @version 1.0 3 | || @author Alexander Brevig 4 | || @contact alexanderbrevig@gmail.com 5 | || 6 | || @description 7 | || | Demonstrates using the KeypadEvent. 8 | || # 9 | */ 10 | #include 11 | 12 | const byte ROWS = 4; //four rows 13 | const byte COLS = 3; //three columns 14 | char keys[ROWS][COLS] = { 15 | {'1','2','3'}, 16 | {'4','5','6'}, 17 | {'7','8','9'}, 18 | {'*','0','#'} 19 | }; 20 | 21 | byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 22 | byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad 23 | 24 | Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 25 | byte ledPin = 13; 26 | 27 | boolean blink = false; 28 | boolean ledPin_state; 29 | 30 | void setup(){ 31 | Serial.begin(9600); 32 | pinMode(ledPin, OUTPUT); // Sets the digital pin as output. 33 | digitalWrite(ledPin, HIGH); // Turn the LED on. 34 | ledPin_state = digitalRead(ledPin); // Store initial LED state. HIGH when LED is on. 35 | keypad.addEventListener(keypadEvent); // Add an event listener for this keypad 36 | } 37 | 38 | void loop(){ 39 | char key = keypad.getKey(); 40 | 41 | if (key) { 42 | Serial.println(key); 43 | } 44 | if (blink){ 45 | digitalWrite(ledPin,!digitalRead(ledPin)); // Change the ledPin from Hi2Lo or Lo2Hi. 46 | delay(100); 47 | } 48 | } 49 | 50 | // Taking care of some special events. 51 | void keypadEvent(KeypadEvent key){ 52 | switch (keypad.getState()){ 53 | case PRESSED: 54 | if (key == '#') { 55 | digitalWrite(ledPin,!digitalRead(ledPin)); 56 | ledPin_state = digitalRead(ledPin); // Remember LED state, lit or unlit. 57 | } 58 | break; 59 | 60 | case RELEASED: 61 | if (key == '*') { 62 | digitalWrite(ledPin,ledPin_state); // Restore LED state from before it started blinking. 63 | blink = false; 64 | } 65 | break; 66 | 67 | case HOLD: 68 | if (key == '*') { 69 | blink = true; // Blink the LED when holding the * key. 70 | } 71 | break; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/examples/HelloKeypad/HelloKeypad.ino: -------------------------------------------------------------------------------- 1 | /* @file HelloKeypad.pde 2 | || @version 1.0 3 | || @author Alexander Brevig 4 | || @contact alexanderbrevig@gmail.com 5 | || 6 | || @description 7 | || | Demonstrates the simplest use of the matrix Keypad library. 8 | || # 9 | */ 10 | #include 11 | 12 | const byte ROWS = 4; //four rows 13 | const byte COLS = 3; //three columns 14 | char keys[ROWS][COLS] = { 15 | {'1','2','3'}, 16 | {'4','5','6'}, 17 | {'7','8','9'}, 18 | {'*','0','#'} 19 | }; 20 | byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 21 | byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad 22 | 23 | Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 24 | 25 | void setup(){ 26 | Serial.begin(9600); 27 | } 28 | 29 | void loop(){ 30 | char key = keypad.getKey(); 31 | 32 | if (key){ 33 | Serial.println(key); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/examples/HelloKeypad3/HelloKeypad3.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | const byte ROWS = 2; // use 4X4 keypad for both instances 5 | const byte COLS = 2; 6 | char keys[ROWS][COLS] = { 7 | {'1','2'}, 8 | {'3','4'} 9 | }; 10 | byte rowPins[ROWS] = {5, 4}; //connect to the row pinouts of the keypad 11 | byte colPins[COLS] = {7, 6}; //connect to the column pinouts of the keypad 12 | Keypad kpd( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 13 | 14 | 15 | const byte ROWSR = 2; 16 | const byte COLSR = 2; 17 | char keysR[ROWSR][COLSR] = { 18 | {'a','b'}, 19 | {'c','d'} 20 | }; 21 | byte rowPinsR[ROWSR] = {3, 2}; //connect to the row pinouts of the keypad 22 | byte colPinsR[COLSR] = {7, 6}; //connect to the column pinouts of the keypad 23 | Keypad kpdR( makeKeymap(keysR), rowPinsR, colPinsR, ROWSR, COLSR ); 24 | 25 | 26 | const byte ROWSUR = 4; 27 | const byte COLSUR = 1; 28 | char keysUR[ROWSUR][COLSUR] = { 29 | {'M'}, 30 | {'A'}, 31 | {'R'}, 32 | {'K'} 33 | }; 34 | // Digitran keypad, bit numbers of PCF8574 i/o port 35 | byte rowPinsUR[ROWSUR] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 36 | byte colPinsUR[COLSUR] = {8}; //connect to the column pinouts of the keypad 37 | 38 | Keypad kpdUR( makeKeymap(keysUR), rowPinsUR, colPinsUR, ROWSUR, COLSUR ); 39 | 40 | 41 | void setup(){ 42 | // Wire.begin( ); 43 | kpdUR.begin( makeKeymap(keysUR) ); 44 | kpdR.begin( makeKeymap(keysR) ); 45 | kpd.begin( makeKeymap(keys) ); 46 | Serial.begin(9600); 47 | Serial.println( "start" ); 48 | } 49 | 50 | //byte alternate = false; 51 | char key, keyR, keyUR; 52 | void loop(){ 53 | 54 | // alternate = !alternate; 55 | key = kpd.getKey( ); 56 | keyUR = kpdUR.getKey( ); 57 | keyR = kpdR.getKey( ); 58 | 59 | if (key){ 60 | Serial.println(key); 61 | } 62 | if( keyR ) { 63 | Serial.println( keyR ); 64 | } 65 | if( keyUR ) { 66 | Serial.println( keyUR ); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/examples/MultiKey/MultiKey.ino: -------------------------------------------------------------------------------- 1 | /* @file MultiKey.ino 2 | || @version 1.0 3 | || @author Mark Stanley 4 | || @contact mstanley@technologist.com 5 | || 6 | || @description 7 | || | The latest version, 3.0, of the keypad library supports up to 10 8 | || | active keys all being pressed at the same time. This sketch is an 9 | || | example of how you can get multiple key presses from a keypad or 10 | || | keyboard. 11 | || # 12 | */ 13 | 14 | #include 15 | 16 | const byte ROWS = 4; //four rows 17 | const byte COLS = 3; //three columns 18 | char keys[ROWS][COLS] = { 19 | {'1','2','3'}, 20 | {'4','5','6'}, 21 | {'7','8','9'}, 22 | {'*','0','#'} 23 | }; 24 | byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the kpd 25 | byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the kpd 26 | 27 | Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 28 | 29 | unsigned long loopCount; 30 | unsigned long startTime; 31 | String msg; 32 | 33 | 34 | void setup() { 35 | Serial.begin(9600); 36 | loopCount = 0; 37 | startTime = millis(); 38 | msg = ""; 39 | } 40 | 41 | 42 | void loop() { 43 | loopCount++; 44 | if ( (millis()-startTime)>5000 ) { 45 | Serial.print("Average loops per second = "); 46 | Serial.println(loopCount/5); 47 | startTime = millis(); 48 | loopCount = 0; 49 | } 50 | 51 | // Fills kpd.key[ ] array with up-to 10 active keys. 52 | // Returns true if there are ANY active keys. 53 | if (kpd.getKeys()) 54 | { 55 | for (int i=0; i 2 | 3 | 4 | const byte ROWS = 4; //four rows 5 | const byte COLS = 3; //three columns 6 | char keys[ROWS][COLS] = { 7 | {'1','2','3'}, 8 | {'4','5','6'}, 9 | {'7','8','9'}, 10 | {'*','0','#'} 11 | }; 12 | byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad 13 | byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad 14 | 15 | Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); 16 | 17 | unsigned long loopCount = 0; 18 | unsigned long timer_t = 0; 19 | 20 | void setup(){ 21 | Serial.begin(9600); 22 | 23 | // Try playing with different debounceTime settings to see how it affects 24 | // the number of times per second your loop will run. The library prevents 25 | // setting it to anything below 1 millisecond. 26 | kpd.setDebounceTime(10); // setDebounceTime(mS) 27 | } 28 | 29 | void loop(){ 30 | char key = kpd.getKey(); 31 | 32 | // Report the number of times through the loop in 1 second. This will give 33 | // you a relative idea of just how much the debounceTime has changed the 34 | // speed of your code. If you set a high debounceTime your loopCount will 35 | // look good but your keypresses will start to feel sluggish. 36 | if ((millis() - timer_t) > 1000) { 37 | Serial.print("Your loop code ran "); 38 | Serial.print(loopCount); 39 | Serial.println(" times over the last second"); 40 | loopCount = 0; 41 | timer_t = millis(); 42 | } 43 | loopCount++; 44 | if(key) 45 | Serial.println(key); 46 | } 47 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/keywords.txt: -------------------------------------------------------------------------------- 1 | # Keypad Library data types 2 | KeyState KEYWORD1 3 | Keypad KEYWORD1 4 | KeypadEvent KEYWORD1 5 | 6 | # Keypad Library constants 7 | NO_KEY LITERAL1 8 | IDLE LITERAL1 9 | PRESSED LITERAL1 10 | HOLD LITERAL1 11 | RELEASED LITERAL1 12 | 13 | # Keypad Library methods & functions 14 | addEventListener KEYWORD2 15 | bitMap KEYWORD2 16 | findKeyInList KEYWORD2 17 | getKey KEYWORD2 18 | getKeys KEYWORD2 19 | getState KEYWORD2 20 | holdTimer KEYWORD2 21 | isPressed KEYWORD2 22 | keyStateChanged KEYWORD2 23 | numKeys KEYWORD2 24 | pin_mode KEYWORD2 25 | pin_write KEYWORD2 26 | pin_read KEYWORD2 27 | setDebounceTime KEYWORD2 28 | setHoldTime KEYWORD2 29 | waitForKey KEYWORD2 30 | 31 | # this is a macro that converts 2d arrays to pointers 32 | makeKeymap KEYWORD2 33 | 34 | # List of objects created in the example sketches. 35 | kpd KEYWORD3 36 | keypad KEYWORD3 37 | kbrd KEYWORD3 38 | keyboard KEYWORD3 39 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/utility/Key.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | || @file Key.cpp 3 | || @version 1.0 4 | || @author Mark Stanley 5 | || @contact mstanley@technologist.com 6 | || 7 | || @description 8 | || | Key class provides an abstract definition of a key or button 9 | || | and was initially designed to be used in conjunction with a 10 | || | state-machine. 11 | || # 12 | || 13 | || @license 14 | || | This library is free software; you can redistribute it and/or 15 | || | modify it under the terms of the GNU Lesser General Public 16 | || | License as published by the Free Software Foundation; version 17 | || | 2.1 of the License. 18 | || | 19 | || | This library is distributed in the hope that it will be useful, 20 | || | but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | || | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 | || | Lesser General Public License for more details. 23 | || | 24 | || | You should have received a copy of the GNU Lesser General Public 25 | || | License along with this library; if not, write to the Free Software 26 | || | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 | || # 28 | || 29 | */ 30 | #include 31 | 32 | 33 | // default constructor 34 | Key::Key() { 35 | kchar = NO_KEY; 36 | kstate = IDLE; 37 | stateChanged = false; 38 | } 39 | 40 | // constructor 41 | Key::Key(char userKeyChar) { 42 | kchar = userKeyChar; 43 | kcode = -1; 44 | kstate = IDLE; 45 | stateChanged = false; 46 | } 47 | 48 | 49 | void Key::key_update (char userKeyChar, KeyState userState, boolean userStatus) { 50 | kchar = userKeyChar; 51 | kstate = userState; 52 | stateChanged = userStatus; 53 | } 54 | 55 | 56 | 57 | /* 58 | || @changelog 59 | || | 1.0 2012-06-04 - Mark Stanley : Initial Release 60 | || # 61 | */ 62 | -------------------------------------------------------------------------------- /twitterKeypad/Keypad/utility/Key.h: -------------------------------------------------------------------------------- 1 | /* 2 | || 3 | || @file Key.h 4 | || @version 1.0 5 | || @author Mark Stanley 6 | || @contact mstanley@technologist.com 7 | || 8 | || @description 9 | || | Key class provides an abstract definition of a key or button 10 | || | and was initially designed to be used in conjunction with a 11 | || | state-machine. 12 | || # 13 | || 14 | || @license 15 | || | This library is free software; you can redistribute it and/or 16 | || | modify it under the terms of the GNU Lesser General Public 17 | || | License as published by the Free Software Foundation; version 18 | || | 2.1 of the License. 19 | || | 20 | || | This library is distributed in the hope that it will be useful, 21 | || | but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | || | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23 | || | Lesser General Public License for more details. 24 | || | 25 | || | You should have received a copy of the GNU Lesser General Public 26 | || | License along with this library; if not, write to the Free Software 27 | || | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 28 | || # 29 | || 30 | */ 31 | 32 | #ifndef KEY_H 33 | #define KEY_H 34 | 35 | // Arduino versioning. 36 | #if defined(ARDUINO) && ARDUINO >= 100 37 | #include "Arduino.h" // for digitalRead, digitalWrite, etc 38 | #else 39 | #include "WProgram.h" 40 | #endif 41 | 42 | #define OPEN LOW 43 | #define CLOSED HIGH 44 | 45 | typedef unsigned int uint; 46 | typedef enum{ IDLE, PRESSED, HOLD, RELEASED } KeyState; 47 | 48 | const char NO_KEY = '\0'; 49 | 50 | class Key { 51 | public: 52 | // members 53 | char kchar; 54 | int kcode; 55 | KeyState kstate; 56 | boolean stateChanged; 57 | 58 | // methods 59 | Key(); 60 | Key(char userKeyChar); 61 | void key_update(char userKeyChar, KeyState userState, boolean userStatus); 62 | 63 | private: 64 | 65 | }; 66 | 67 | #endif 68 | 69 | /* 70 | || @changelog 71 | || | 1.0 2012-06-04 - Mark Stanley : Initial Release 72 | || # 73 | */ 74 | -------------------------------------------------------------------------------- /twitterKeypad/twitterKeypad/twitterKeypad.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Tweet from ESP via taking text from keypad 3 | * Taken help from - http://community.thingspeak.com/tutorials/arduino/update-twitter-with-thingtweet-and-arduino-ethernet-shield/ 4 | * Developed by Madhukant(kantmadhu956@gmail.com) & Tushar Gupta (tushargupta5197@gmail.com) 5 | * Date modified - 7/3/2016 6 | */ 7 | #include 8 | #include 9 | #include // Core graphics library 10 | #include // Hardware-specific library 11 | #include 12 | 13 | #define TFT_CS 48 14 | #define TFT_RST 47 // you can also connect this to the Arduino reset 15 | // in which case, set this #define pin to 0! 16 | #define TFT_DC 49 17 | 18 | Adafruit_ST7735 lcd = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 19 | 20 | 21 | // definations 22 | #define DEBUG true 23 | 24 | #define APIKEY "9Y26X3INFNTUIIP5" // your thingspeak twitter api key 25 | #define TARGET_IP "api.thingspeak.com" // direction IP thingspeak 26 | #define TARGET_PORT "80" // port 80 27 | #define ID "Jarvis" // name of wireless access point to connect to 28 | #define PASS "wehavehulk" // wifi password 29 | 30 | boolean tweet = false; 31 | //*******************text variables******************************* 32 | char customKey; 33 | const byte ROWS = 4; 34 | const byte COLS = 4; 35 | 36 | char keys[ROWS][COLS] = { 37 | {'1','2','3','+'}, 38 | {'4','5','6','-'}, 39 | {'7','8','9','*'}, 40 | {'C','0','=','/'} 41 | }; 42 | byte rowPins[ROWS] = {3,2,5,6}; //connect to the row pinouts of the keypad 43 | byte colPins[COLS] = {8,9,10,11}; //connect to the column pinouts of the keypad 44 | 45 | //initialize an instance of class NewKeypad 46 | Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); 47 | //*****************scientific buttons****************** 48 | 49 | int curx=0,cury=0; 50 | char msg[140]; 51 | int space=7; 52 | int spacey=10; 53 | 54 | int waittime=500; 55 | 56 | int times[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 57 | long timelapse=millis(); 58 | int index=0; 59 | //***************************************************** 60 | void text(){ 61 | while(1){ 62 | char c; 63 | 64 | customKey = customKeypad.getKey(); 65 | if(customKey!=NO_KEY) 66 | { 67 | if(customKey=='=') 68 | break; 69 | switch(customKey) 70 | { 71 | case '1': 72 | if(times[1]==0) 73 | { c='@'; 74 | msg[index]=c; 75 | index++; 76 | times[1]=1; 77 | timelapse=millis(); 78 | } 79 | else if(times[1]==1) 80 | { 81 | index--; 82 | c='#'; 83 | msg[index]=c; 84 | index++; 85 | curx-=space; 86 | times[1]=2; 87 | timelapse=millis(); 88 | } 89 | else 90 | { 91 | index--; 92 | c='.'; 93 | msg[index]=c; 94 | index++; 95 | curx-=space; 96 | times[1]=0; 97 | timelapse=0; 98 | } 99 | break; 100 | 101 | 102 | 103 | case '2': 104 | if(times[2]==0) 105 | { c='a'; 106 | msg[index]=c; 107 | index++; 108 | times[2]=1; 109 | timelapse=millis(); 110 | } 111 | else if(times[2]==1) 112 | { 113 | index--; 114 | c='b'; 115 | msg[index]=c; 116 | index++; 117 | curx-=space; 118 | times[2]=2; 119 | timelapse=millis(); 120 | } 121 | else 122 | { 123 | index--; 124 | c='c'; 125 | msg[index]=c; 126 | index++; 127 | curx-=space; 128 | times[2]=0; 129 | timelapse=0; 130 | } 131 | break; 132 | 133 | 134 | case '3': 135 | if(times[3]==0) 136 | { c='d'; 137 | msg[index]=c; 138 | index++; 139 | times[3]=1; 140 | timelapse=millis(); 141 | } 142 | else if(times[3]==1) 143 | { 144 | index--; 145 | c='e'; 146 | msg[index]=c; 147 | index++; 148 | curx-=space; 149 | times[3]=2; 150 | timelapse=millis(); 151 | } 152 | else 153 | { 154 | index--; 155 | c='f'; 156 | msg[index]=c; 157 | index++; 158 | curx-=space; 159 | times[3]=0; 160 | timelapse=0; 161 | } 162 | break; 163 | 164 | case '4': 165 | if(times[4]==0) 166 | { c='g'; 167 | msg[index]=c; 168 | index++; 169 | times[4]=1; 170 | timelapse=millis(); 171 | } 172 | else if(times[4]==1) 173 | { 174 | index--; 175 | c='h'; 176 | msg[index]=c; 177 | index++; 178 | curx-=space; 179 | times[4]=2; 180 | timelapse=millis(); 181 | } 182 | else 183 | { 184 | index--; 185 | c='i'; 186 | msg[index]=c; 187 | index++; 188 | curx-=space; 189 | times[4]=0; 190 | timelapse=0; 191 | } 192 | break; 193 | 194 | 195 | case '5': 196 | if(times[5]==0) 197 | { c='j'; 198 | msg[index]=c; 199 | index++; 200 | times[5]=1; 201 | timelapse=millis(); 202 | } 203 | else if(times[5]==1) 204 | { 205 | index--; 206 | c='k'; 207 | msg[index]=c; 208 | index++; 209 | curx-=space; 210 | times[5]=2; 211 | timelapse=millis(); 212 | } 213 | else 214 | { 215 | index--; 216 | c='l'; 217 | msg[index]=c; 218 | index++; 219 | curx-=space; 220 | times[5]=0; 221 | timelapse=0; 222 | } 223 | break; 224 | 225 | 226 | case '6': 227 | if(times[6]==0) 228 | { c='m'; 229 | msg[index]=c; 230 | index++; 231 | times[6]=1; 232 | timelapse=millis(); 233 | } 234 | else if(times[6]==1) 235 | { 236 | index--; 237 | c='n'; 238 | msg[index]=c; 239 | index++; 240 | curx-=space; 241 | times[6]=2; 242 | timelapse=millis(); 243 | } 244 | else 245 | { 246 | index--; 247 | c='o'; 248 | msg[index]=c; 249 | index++; 250 | curx-=space; 251 | times[6]=0; 252 | timelapse=0; 253 | } 254 | break; 255 | 256 | case '7': 257 | if(times[7]==0) 258 | { c='p'; 259 | msg[index]=c; 260 | index++; 261 | times[7]=1; 262 | timelapse=millis(); 263 | } 264 | else if(times[7]==1) 265 | { 266 | index--; 267 | c='q'; 268 | msg[index]=c; 269 | index++; 270 | curx-=space; 271 | times[7]=2; 272 | timelapse=millis(); 273 | } 274 | else if(times[7]==2) 275 | { 276 | index--; 277 | c='r'; 278 | msg[index]=c; 279 | index++; 280 | curx-=space; 281 | times[7]=3; 282 | timelapse=millis(); 283 | } 284 | else 285 | { 286 | index--; 287 | c='s'; 288 | msg[index]=c; 289 | index++; 290 | curx-=space; 291 | times[7]=0; 292 | timelapse=0; 293 | } 294 | break; 295 | 296 | case '8': 297 | if(times[8]==0) 298 | { c='t'; 299 | msg[index]=c; 300 | index++; 301 | times[8]=1; 302 | timelapse=millis(); 303 | } 304 | else if(times[8]==1) 305 | { 306 | index--; 307 | c='u'; 308 | msg[index]=c; 309 | index++; 310 | curx-=space; 311 | times[8]=2; 312 | timelapse=millis(); 313 | } 314 | else 315 | { 316 | index--; 317 | c='v'; 318 | msg[index]=c; 319 | index++; 320 | curx-=space; 321 | times[8]=0; 322 | timelapse=0; 323 | } 324 | break; 325 | 326 | 327 | case '9': 328 | if(times[9]==0) 329 | { c='w'; 330 | msg[index]=c; 331 | index++; 332 | times[9]=1; 333 | timelapse=millis(); 334 | } 335 | else if(times[9]==1) 336 | { 337 | index--; 338 | c='x'; 339 | msg[index]=c; 340 | index++; 341 | curx-=space; 342 | times[9]=2; 343 | timelapse=millis(); 344 | } 345 | else if(times[9]==2) 346 | { 347 | index--; 348 | c='y'; 349 | msg[index]=c; 350 | index++; 351 | curx-=space; 352 | times[9]=3; 353 | timelapse=millis(); 354 | } 355 | else 356 | { 357 | index--; 358 | c='z'; 359 | msg[index]=c; 360 | index++; 361 | curx-=space; 362 | times[9]=0; 363 | timelapse=0; 364 | } 365 | break; 366 | case 'C': 367 | { 368 | if(curx!=0) 369 | curx=curx-space; 370 | else 371 | { 372 | curx=133; 373 | int tempy=cury; 374 | cury-=spacey; 375 | 376 | } 377 | msg[index-1]='\0'; 378 | if(index>0) 379 | index--; 380 | 381 | c=' '; 382 | //lcd.setCursor(curx,cury); 383 | //lcd.print("."); 384 | } 385 | break; 386 | case '0': 387 | c=' '; 388 | msg[index]=c; 389 | index++; 390 | curx+=space; 391 | break; 392 | } 393 | lcd.setCursor(curx,cury); 394 | if(c<='z'&&c>='a'||c==' '||c=='@'||c=='#'||c=='.') 395 | { lcd.print(c); 396 | if(c!=' ') 397 | curx+=space; 398 | } 399 | Serial.println(msg); 400 | Serial.println(index); 401 | 402 | 403 | } 404 | if(millis()>timelapse+waittime) 405 | setallzero(); 406 | if(curx>=140&&millis()>timelapse+waittime){ 407 | curx=0; 408 | cury+=spacey; 409 | } 410 | } 411 | tweet=true; 412 | } 413 | void setup() 414 | { 415 | Serial.begin(115200); // debug serial port 416 | Serial3.begin(115200); // esp serial port 417 | pinMode(38,INPUT); 418 | lcd.initR(INITR_BLACKTAB); 419 | lcd.fillScreen(ST7735_BLACK); 420 | lcd.setRotation(1); //to set the TFT screen Landscape 421 | lcd.setTextWrap(false); 422 | lcd.setTextColor(ST7735_WHITE,ST7735_BLACK); 423 | 424 | delay(1000); // initial delay 425 | 426 | sendData("AT+RST\r\n",1000,DEBUG); // reset ESP8266 427 | 428 | sendData("AT+CWMODE=1\r\n",1000,DEBUG); // configure ESP8266 mode 429 | 430 | // connect to internet via wireless network 431 | String cmd="AT+CWJAP=\""; 432 | cmd+=ID; 433 | cmd+="\",\""; 434 | cmd+=PASS; 435 | cmd+="\""; 436 | sendData( cmd+"\r\n",1000,DEBUG); 437 | 438 | delay(1000); 439 | 440 | sendData("AT+CIPMUX=0\r\n",1000,DEBUG); // Configure server connection type 441 | 442 | } 443 | 444 | void loop() 445 | { 446 | text(); 447 | String twitter_status = msg; 448 | lcd.fillScreen(ST7735_BLACK); 449 | lcd.setCursor(0,0); 450 | lcd.print("Message Recieved press button to tweet"); 451 | delay(1000); 452 | if(digitalRead(38) == true && !tweet){ 453 | tweet = true; 454 | lcd.fillScreen(ST7735_BLACK); 455 | lcd.setCursor(0,0); 456 | lcd.print("Preparing Tweet"); 457 | } 458 | 459 | if(tweet){ 460 | String connection_command = "AT+CIPSTART=\"TCP\",\""; 461 | connection_command += TARGET_IP; 462 | connection_command += "\",80\r\n"; 463 | 464 | sendData(connection_command,1000,DEBUG); 465 | 466 | // Create HTTP POST Data 467 | String tsData = "api_key=" APIKEY "&status=" + twitter_status ; 468 | 469 | String tweet_request = "POST /apps/thingtweet/1/statuses/update HTTP/1.1\n"; 470 | tweet_request += "Host: api.thingspeak.com\n"; 471 | tweet_request += "Connection: close\n"; 472 | tweet_request += "Content-Type: application/x-www-form-urlencoded\n"; 473 | tweet_request += "Content-Length: "; 474 | tweet_request += tsData.length(); 475 | tweet_request += "\n\n"; 476 | tweet_request += tsData; 477 | 478 | 479 | String send_request = "AT+CIPSEND="; 480 | send_request += tweet_request.length(); 481 | send_request +="\r\n"; 482 | 483 | sendData(send_request,1000,DEBUG); 484 | sendData(tweet_request,1000,DEBUG); 485 | 486 | // close server connection after tweet 487 | sendData("AT+CIPCLOSE=0\r\n",1500,DEBUG); 488 | 489 | delay(2000); // thingspeak delay 490 | 491 | lcd.fillScreen(ST7735_BLACK); 492 | lcd.setCursor(0,0); 493 | lcd.print("Twitter Status- "); 494 | //lcd.setCursor(0,20); 495 | lcd.print("Updated"); 496 | 497 | delay(8000); // thingspeak delay 498 | tweet = false; 499 | } 500 | } 501 | 502 | // send AT command function 503 | String sendData(String command, const int timeout, boolean debug) 504 | { 505 | String response = ""; 506 | 507 | Serial3.print(command); // send the read character to the esp8266 508 | 509 | long int time = millis(); 510 | 511 | while( (time+timeout) > millis()) 512 | { 513 | while(Serial3.available()) 514 | { 515 | // The esp has data so display its output to the serial window 516 | char c = Serial3.read(); // read the next character. 517 | response += c; 518 | } 519 | } 520 | 521 | if(debug) 522 | { 523 | Serial.print(response); 524 | } 525 | 526 | return response; 527 | } 528 | void setallzero(){ 529 | int i; 530 | for(i=0;i<14;i++) 531 | times[i]=0; 532 | } 533 | --------------------------------------------------------------------------------