Advertisement
Guest User

oldschool texter

a guest
Feb 14th, 2014
97
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Clayton Ford
  2. //With assistance from Mark Tortorich
  3. //Texting old-school style with a Hitachi-compatible 16x2 LCD and a 4x4 keypad
  4. //with added text storage and serial return of typed text.
  5. //This code and hardware setup, without much additional effort, could actually
  6. //send text messages upon the addition of a cellular shield and relatively
  7. //minor changes to this code.
  8.  
  9. #include <LiquidCrystal.h> //include the lcd library
  10. const byte row1=3; //keypad row pins, shared with the lcd data lines
  11. const byte row2=4;
  12. const byte row3=5;
  13. const byte row4=6;
  14. const byte col1=7; //keypad column lines
  15. const byte col2=8;
  16. const byte col3=9;
  17. const byte col4=10;
  18. LiquidCrystal lcd(12, 11, row4, row3, row2, row1); //lcd object
  19. byte numpressed; //latest number pressed on the keypad
  20. byte timespressed; //times the number has been pressed
  21. byte cursorx=0; //cursor x position
  22. byte cursory=0; //cursor y position
  23. char letter; //stores letter that needs to be printed to the lcd
  24. const int wait=1000; //time to wait for additional presses to same number
  25. const int preventholddelay=150; //time to wait to prevent cycling through things too quickly
  26. unsigned long basetime; //base time for while loop
  27. unsigned long elapsed=0; //elapsed time in while loop
  28. byte lastnumpressed; //the initial number pressed on the keypad
  29. bool disablespacedelay=false; //disables the delay in the space function in the case that a different number is pressed while in while loop
  30. const byte maxtimespressed[16]={
  31. 1,3,4,4,4,4,4,4,4,4,1,7,1,1,1,1}; //stores maximum number of times any given key can be pressed before looping back to its first letter (used by incrementtimespressed function)
  32. char typedtext[140]; //stores typed text for printout to the serial console
  33. int positionintypedtext=0; //position in typedtext character array
  34. int charremaining; //remaining characters in message
  35. bool promptkeypress=false; //used for waiting for, and keypress detection, at the end-of composition prompt
  36.  
  37. void setup(){
  38. Serial.begin(115200); //start serial communication so that we can print the typed text to the serial console
  39. lcd.begin(16,2); //initialize the lcd
  40. lcd.setCursor(cursorx,cursory); //set the lcd cursor
  41. lcd.noCursor(); //turn off the cursor
  42. pinMode(row1,OUTPUT); //set the rows as outputs
  43. pinMode(row2,OUTPUT);
  44. pinMode(row3,OUTPUT);
  45. pinMode(row4,OUTPUT);
  46. pinMode(col1,INPUT); //set the columns as inputs
  47. pinMode(col2,INPUT);
  48. pinMode(col3,INPUT);
  49. pinMode(col4,INPUT);
  50. delay(wait);
  51. lcd.cursor(); //turn the cursor on again after a delay equivalent to wait
  52. rowshigh(); //sets all rows high
  53. }
  54.  
  55. void loop(){
  56. numpressed=16; //reset "numpressed" (16 doesn't refer to any button on the pad)
  57. if (findpress()){ //look for presses, if one has occurred, identify it and continue
  58. timespressed=0; //reset "timespressed"
  59. if (numpressed==0){ //if zero on the pad was pressed,
  60. dozero(); //print zero
  61. letter='0'; //manually seed a zero as the character for the text storage
  62. textstorage(1); //regular character storage
  63. }
  64. if (numpressed==10){ //if shift on the pad was pressed,
  65. textstorage(2); //perform a space in storage
  66. dospace(); //do a space
  67. }
  68. if (numpressed==14){ //if the arrows on the pad were pressed,
  69. textstorage(3); //perform a backspace in storage
  70. dobackspace(); //do a backspace
  71. }
  72. if (numpressed==15){ //if enter on the pad was pressed,
  73. outputserial(); //output message and display remaining characters to serial console
  74. }
  75. if ((numpressed<10&&numpressed>0)||numpressed==11){ //if 1,2,3,4,5,6,7,8,9, or 11 was pressed (any one of the keys with multiple characters assigned),
  76. lastnumpressed=numpressed; //record which number was pressed,
  77. basetime=millis(); //and take a base time for the while loop
  78. while (elapsed<wait){ //while below the time to wait,
  79. if(findpress()){ //look for presses, if one has occurred, identify it and continue
  80. if (numpressed==lastnumpressed){ //if it was the same as before,
  81. incrementtimespressed(); //increment "timespressed"
  82. basetime=basetime+(wait-(wait-elapsed)); //roll up the base time, to allow another wait period until next press of the same button
  83. definepress(); //use "numpressed" and "timespressed" to define "letter"
  84. lcd.print(letter); //print the letter that was defined
  85. lcd.setCursor(cursorx,cursory); //maintain cursor position
  86. rowshigh(); //return all rows high
  87. delay(preventholddelay); //delay a little to prevent continuous cycling through "timespressed" during a single press
  88. }
  89. else{ //if the number that was pressed was different than before,
  90. disablespacedelay=true; //disable the delay in the space function to allow the press to be detected a second time, at the beginning of void loop
  91. break; //break out of the while loop
  92. }
  93. }
  94. elapsed=millis()-basetime; //refresh the elapsed time for the while loop
  95. }
  96. elapsed=0; //reset the elapsed time for the while loop
  97. textstorage(1); //store character
  98. dospace(); //do a space
  99. }
  100. }
  101. if (positionintypedtext==139){ //if the end of the stored text has been reached,
  102. promptkeypress=false; //reset keypress detection
  103. cursorx=0; //set cursor to the beginning of first row
  104. cursory=0;
  105. lcd.setCursor(cursorx,cursory);
  106. lcd.print("Msg end. <>=back"); //print this out to the lcd
  107. cursorx=0; //set cursor to the beginning of second row
  108. cursory=1;
  109. lcd.setCursor(cursorx,cursory);
  110. lcd.print("enter=serial out"); //print this out to the lcd
  111. rowshigh(); //sets all rows high
  112. numpressed=16; //reset "numpressed" (16 doesn't refer to any button on the pad)
  113. while(!promptkeypress){ //while no relevant keypresses have occurred,
  114. if (findpress()){ //look for presses, if one has occurred, identify it and continue
  115. timespressed=0; //reset "timespressed"
  116. if (numpressed==14){ //if the arrows on the pad were pressed,
  117. promptkeypress=true; //take note so that the while loop can be broken
  118. textstorage(3); //perform a backspace in storage
  119. for (int i=0;i<16;i++){ //print out to the first line on the lcd from the stored text
  120. cursorx=i;
  121. cursory=0;
  122. lcd.setCursor(cursorx,cursory);
  123. lcd.print(typedtext[108+i]);
  124. }
  125. for (int j=0;j<16;j++){ //print out to the second line on the lcd from the stored text
  126. cursorx=j;
  127. cursory=1;
  128. lcd.setCursor(cursorx,cursory);
  129. lcd.print(typedtext[123+j]);
  130. }
  131. cursorx=15; //set cursor to the beginning of second row
  132. cursory=1;
  133. lcd.setCursor(cursorx,cursory);
  134. rowshigh(); //sets all rows high
  135. }
  136. if (numpressed==15){ //if enter on the pad was pressed,
  137. promptkeypress=true; //take note so that the while loop can be broken
  138. Serial.print("Final message: "); //print this to the serial console
  139. Serial.println(typedtext); //print out all the text typed so far to the serial console
  140. Serial.println(); //print a blank line
  141. for (int i=0;i<140;i++){ //write all positions in the stored text to be blank
  142. typedtext[i]=' ';
  143. }
  144. positionintypedtext=0; //reset the position in the stored text to the beginning
  145. doclear();
  146. rowshigh(); //sets all rows high
  147. }
  148. }
  149. }
  150. delay(preventholddelay); //delay a little to prevent continuous cycling
  151. }
  152. }
  153.  
  154. void rowshigh(){ //sets all rows high
  155. digitalWrite(row1,HIGH); //write all the rows high
  156. digitalWrite(row2,HIGH);
  157. digitalWrite(row3,HIGH);
  158. digitalWrite(row4,HIGH);
  159. }
  160.  
  161. bool findpress(){ //finds a press to define "numpressed", if any press occurs, returns true
  162. bool pressfound=false; //variable for any press detection, is returned by this function
  163.  
  164. digitalWrite(row1,LOW); //write all rows low
  165. digitalWrite(row2,LOW);
  166. digitalWrite(row3,LOW);
  167. digitalWrite(row4,LOW);
  168.  
  169. digitalWrite(row1,HIGH); //write first row high
  170. if (digitalRead(col1)==HIGH){ //if the first column is now high, "1" has been pressed
  171. numpressed = 1;
  172. pressfound=true;
  173. }
  174. if (digitalRead(col2)==HIGH){ //if the second column is now high, "2" has been pressed
  175. numpressed = 2;
  176. pressfound=true;
  177. }
  178. if (digitalRead(col3)==HIGH){ //if the third column is now high, "3" has been pressed
  179. numpressed = 3;
  180. pressfound=true;
  181. }
  182. if (digitalRead(col4)==HIGH){ //if the fourth column is now high, "reset" has been pressed
  183. numpressed = 12;
  184. pressfound=true;
  185. }
  186. digitalWrite(row1,LOW); //return first row low
  187.  
  188. digitalWrite(row2,HIGH); //write second row high
  189. if (digitalRead(col1)==HIGH){ //if the first column is now high, "4" has been pressed
  190. numpressed = 4;
  191. pressfound=true;
  192. }
  193. if (digitalRead(col2)==HIGH){ //if the second column is now high, "5" has been pressed
  194. numpressed = 5;
  195. pressfound=true;
  196. }
  197. if (digitalRead(col3)==HIGH){ //if the third column is now high, "6" has been pressed
  198. numpressed = 6;
  199. pressfound=true;
  200. }
  201. if (digitalRead(col4)==HIGH){ //if the fourth column is now high, "dial" has been pressed
  202. numpressed = 13;
  203. pressfound=true;
  204. }
  205. digitalWrite(row2,LOW); //return second row low
  206.  
  207. digitalWrite(row3,HIGH); //write third row high
  208. if (digitalRead(col1)==HIGH){ //if the first column is now high, "7" has been pressed
  209. numpressed = 7;
  210. pressfound=true;
  211. }
  212. if (digitalRead(col2)==HIGH){ //if the second column is now high, "8" has been pressed
  213. numpressed = 8;
  214. pressfound=true;
  215. }
  216. if (digitalRead(col3)==HIGH){ //if the third column is now high, "9" has been pressed
  217. numpressed = 9;
  218. pressfound=true;
  219. }
  220. if (digitalRead(col4)==HIGH){ //if the fourth column is now high, the arrows have been pressed
  221. numpressed = 14;
  222. pressfound=true;
  223. }
  224. digitalWrite(row3,LOW); //return third row low
  225.  
  226. digitalWrite(row4,HIGH); //write fourth row high
  227. if (digitalRead(col1)==HIGH){ //if the first column is now high, "shift" has been pressed
  228. numpressed = 10;
  229. pressfound=true;
  230. }
  231. if (digitalRead(col2)==HIGH){ //if the second column is now high, "0" has been pressed
  232. numpressed = 0;
  233. pressfound=true;
  234. }
  235. if (digitalRead(col3)==HIGH){ //if the third column is now high, "." has been pressed
  236. numpressed = 11;
  237. pressfound=true;
  238. }
  239. if (digitalRead(col4)==HIGH){ //if the fourth column is now high, "enter" has been pressed
  240. numpressed = 15;
  241. pressfound=true;
  242. }
  243. digitalWrite(row4,LOW); //return fourth row low
  244.  
  245. rowshigh(); //write all rows high
  246.  
  247. return pressfound; //function returns true if any press found, otherwise returns false
  248. }
  249.  
  250. void definepress(){ //uses "lastnumpressed" and "timespressed" to define "letter"
  251. if (lastnumpressed==1){
  252. if (timespressed==1){
  253. letter='Q';
  254. }
  255. if (timespressed==2){
  256. letter='Z';
  257. }
  258. if (timespressed==3){
  259. letter='1';
  260. }
  261. }
  262. if (lastnumpressed==2){
  263. if (timespressed==1){
  264. letter='A';
  265. }
  266. if (timespressed==2){
  267. letter='B';
  268. }
  269. if (timespressed==3){
  270. letter='C';
  271. }
  272. if (timespressed==4){
  273. letter='2';
  274. }
  275. }
  276. if (lastnumpressed==3){
  277. if (timespressed==1){
  278. letter='D';
  279. }
  280. if (timespressed==2){
  281. letter='E';
  282. }
  283. if (timespressed==3){
  284. letter='F';
  285. }
  286. if (timespressed==4){
  287. letter='3';
  288. }
  289. }
  290. if (lastnumpressed==4){
  291. if (timespressed==1){
  292. letter='G';
  293. }
  294. if (timespressed==2){
  295. letter='H';
  296. }
  297. if (timespressed==3){
  298. letter='I';
  299. }
  300. if (timespressed==4){
  301. letter='4';
  302. }
  303. }
  304. if (lastnumpressed==5){
  305. if (timespressed==1){
  306. letter='J';
  307. }
  308. if (timespressed==2){
  309. letter='K';
  310. }
  311. if (timespressed==3){
  312. letter='L';
  313. }
  314. if (timespressed==4){
  315. letter='5';
  316. }
  317. }
  318. if (lastnumpressed==6){
  319. if (timespressed==1){
  320. letter='M';
  321. }
  322. if (timespressed==2){
  323. letter='N';
  324. }
  325. if (timespressed==3){
  326. letter='O';
  327. }
  328. if (timespressed==4){
  329. letter='6';
  330. }
  331. }
  332. if (lastnumpressed==7){
  333. if (timespressed==1){
  334. letter='P';
  335. }
  336. if (timespressed==2){
  337. letter='R';
  338. }
  339. if (timespressed==3){
  340. letter='S';
  341. }
  342. if (timespressed==4){
  343. letter='7';
  344. }
  345. }
  346. if (lastnumpressed==8){
  347. if (timespressed==1){
  348. letter='T';
  349. }
  350. if (timespressed==2){
  351. letter='U';
  352. }
  353. if (timespressed==3){
  354. letter='V';
  355. }
  356. if (timespressed==4){
  357. letter='8';
  358. }
  359. }
  360. if (lastnumpressed==9){
  361. if (timespressed==1){
  362. letter='W';
  363. }
  364. if (timespressed==2){
  365. letter='X';
  366. }
  367. if (timespressed==3){
  368. letter='Y';
  369. }
  370. if (timespressed==4){
  371. letter='9';
  372. }
  373. }
  374. if (lastnumpressed==11){
  375. if (timespressed==1){
  376. letter='.';
  377. }
  378. if (timespressed==2){
  379. letter='?';
  380. }
  381. if (timespressed==3){
  382. letter='!';
  383. }
  384. if (timespressed==4){
  385. letter=',';
  386. }
  387. if (timespressed==5){
  388. letter='\'';
  389. }
  390. if (timespressed==6){
  391. letter='"';
  392. }
  393. if (timespressed==7){
  394. letter='-';
  395. }
  396. }
  397. }
  398.  
  399. void incrementtimespressed(){ //increment "timespressed" until at max value stored in maxtimespressed for that lastnumpressed, then roll over to 1
  400. if (timespressed==maxtimespressed[lastnumpressed]){ //if at the maximum,
  401. timespressed=1; //roll over timespressed to one
  402. }
  403. else{ //otherwise,
  404. timespressed++; //increment timespressed
  405. }
  406. }
  407.  
  408. void dozero(){ //prints zero
  409. lcd.print('0'); //print 0
  410. lcd.setCursor(cursorx,cursory); //maintain cursor position
  411. dospace(); //space
  412. }
  413.  
  414. void dospace(){ //moves cursor forward once, wraps to next line if necessary, clears and returns to top of display if at bottom
  415. if (cursory==1){ //if on the bottom row,
  416. if (cursorx==15){ //if at the end of the row,
  417. cursorx=0; //define new cursor position as the upper-left corner
  418. cursory=0;
  419. lcd.clear(); //clear the lcd
  420. }
  421. else{ //otherwise,
  422. cursorx++; //increment the cursor to the right
  423. }
  424. }
  425. else{ //if on the top row,
  426. if (cursorx==15){ //if at the end of the row,
  427. cursorx=0; //define new cursor position as the bottom-left corner
  428. cursory=1;
  429. }
  430. else{ //otherwise,
  431. cursorx++; //increment the cursor to the right
  432. }
  433. }
  434. lcd.setCursor(cursorx,cursory); //set cursor to defined location
  435. rowshigh(); //sets all rows high
  436. if (disablespacedelay){ //if the delay has been disabled,
  437. disablespacedelay=false; //reset its being disabled
  438. }
  439. else{ //otherwise,
  440. delay(preventholddelay); //delay a bit
  441. }
  442. }
  443.  
  444. void doclear(){ //clears and returns to top-left of display
  445. cursorx=0;
  446. cursory=0;
  447. lcd.clear();
  448. lcd.setCursor(cursorx,cursory);
  449. rowshigh(); //sets all rows high
  450. delay(preventholddelay);
  451. }
  452.  
  453. void dobackspace(){ //does a backspace, essentially the opposite of dospace
  454. if (cursory==1){
  455. if (cursorx==0){
  456. cursorx=15;
  457. cursory=0;
  458. }
  459. else{
  460. cursorx--;
  461. }
  462. }
  463. else{
  464. if (cursorx==0){
  465. cursorx=0;
  466. cursory=0;
  467. }
  468. else{
  469. cursorx--;
  470. }
  471. }
  472. lcd.setCursor(cursorx,cursory);
  473. lcd.print(" ");
  474. lcd.setCursor(cursorx,cursory);
  475. rowshigh(); //sets all rows high
  476. delay(preventholddelay);
  477. }
  478.  
  479. void textstorage(byte mode){ //contains functions for text storage
  480. if (mode==1){ //regular character storage
  481. typedtext[positionintypedtext]=letter; //store letter that was printed to LCD in typedtext
  482. positionintypedtext++; //increment position in typedtext
  483. }
  484. if (mode==2){ //do a space in stored text
  485. typedtext[positionintypedtext]=' '; //set current position in typedtext to a space
  486. positionintypedtext++; //increment position in typedtext
  487. }
  488. if (mode==3){ //does a backspace in the stored text
  489. positionintypedtext--; //decrement position in typedtext
  490. typedtext[positionintypedtext]=' '; //set current position in typedtext to a space
  491. }
  492. }
  493.  
  494. void outputserial(){ //output message and display remaining characters to serial console
  495. Serial.print("Message: ");
  496. Serial.println(typedtext); //print out all the text typed so far to the serial console
  497. charremaining=(139-(positionintypedtext)); //calculate remaining characters
  498. Serial.print(charremaining); //display remaining characters
  499. if (charremaining==1){ //making sure that the plural is only used correctly
  500. Serial.println(" character remaining");
  501. }
  502. else{
  503. Serial.println(" characters remaining");
  504. }
  505. Serial.println(); //print a blank line
  506. delay(preventholddelay); //delay a little to prevent continuous cycling
  507. }
Advertisement
RAW Paste Data Copied
Advertisement