There is no other tool available which helps in easy prototyping like the Arduino does. The arduino board has all the required circuitry to get the built-in AVR microcontroller running. The output or inputs can be taken from the boards or given to the board using convenient connectors. Both digital and analog I/O pins are available in all Arduino boards. The arduino boards can also communicate with other devices using standard communication ports like USART, IIC, and USB etc. The most impressive thing is that most of the Arduino boards are bread-board compatible which keeps both the hobbyist and developers interested in it.
In this project a GSM module is interfaced with the Arduino board using the USART communication port. A PS2 keyboard is also interfaced with the Arduino board with the help of normal I/O pins. The keyboard can be used to type an SMS and the number to which the SMS needs to be send and the Arduino board will make the GSM module to perform the task. All the letters which are typed using the Keyboard and the information from the Arduino board are displayed on a 16*2 LCD also. Thus in this project the Arduino board forms a system with the Keyboard as input device, LCD as output device and the GSM module as the wireless communication device.
The GSM module used in this project is a SIM900 based module which can communicate with other devices using RS232 serial communication port. It works on 9V power supply and the image of the same is given below:
Fig. 2: SIM900 GSM Module connected to Tx pin of Arduino board module through max232
TTL logic levels a max232 IC is used to make a bi-directional conversion between the RS232 and TTL logic levels. The Tx pin of the Arduino board is connected to the Rx pin of the GSM module through the max232 and the Rx pin of the Arduino is connected to the Tx pin of the GSM module using max232 itself.
The working of this project is explained based on the Arduino pro-mini board and the IDE version 1.0.3 for windows. The advantage of this board is that it comes in very small in size; any kind of connectors can be soldered on its periphery according to our requirements. It is very breadboard friendly and occupies very less space of a typical breadboard.
The image of the Arduino pro-mini board and the Arduino IDE are shown below:
Fig. 3: Typical Arduino Pro-Mini Board
Fig. 4: Arduino IDE Software Window
Since the Arduino pro-mini board has no circuitry for interfacing it with the serial port or the USB port of the PC, an external USB to TTL converter board is required to connect it with the PC. This hardware helps in programming the Arduino board and also helps in the serial communication with the USB port of the PC.
Fig. 5: External USB to TTL converter board for programming Arduino and serial communication
It is assumed that the reader has gone through the project how to get started with the Arduino and tried out all the things discussed there.
The code written in the Arduino is able to communicate with the GSM module using AT commands. The AT commands are send or received from the module using the serial communication functions provided by the Arduino library. The functions like Serial.begin() which helps to initialize the serial port with a given baud rate, Serial.write() to send a data to the serial port, Serial.available() and Serial.read() functions to read data from the serial port are used in this project and they are already discussed in previous projects on how to do serial communication with the Arduino, how to send and receive serial data using arduino and how to do serial debugging with the Arduino.
GSM modules respond “OK” when it receives the command “AT” and it is the best way of check communication between the module and the microcontroller.
AT+CMGS – This command is used to send the SMS from a GSM module. The command should be followed by the number to which the message needs to be sent. After a Carriage return one can send the SMS text to the GSM module which is then send after it receives a <CTRL+Z>
The syntax for sending a SMS using the AT commands with a GSM module is shown below;
SYNTAX : AT+CMGS=”mobile_number” <ENTER><write the text><CTRL+Z>
For example to send an SMS “hello” to the number 123456789 the following command can be used;
AT+CMGS=”123456789”<ENTER>hello<CTRL+Z>
The implementation of the project which can receive the SMS text and the number to which it needs to be send from the PS2 keyboard and use them to send SMS with the help of the GSM module is represented using the following block diagram:
Fig. 6: Block Diagram Of Sending And Reciving SMS Using PS2 Keyboard and GSM Module With Arduino
The code for this project is so written that it will send the string “AT+CMGS=”” to the GSM module first and then waits for the user to enter the required number using the standard PS2 keyboard. The Arduino reads the data from the PS2 keyboard using functions from the custom PS2 library file called “PS2Keyboard.h” which has all the necessary routines for accessing a PS2 keyboard. There are basically three functions which the user can directly make use in their code and are namely keyboard.begin()”,keyboard.available() and “keyboard.read()”. The details of how to use these functions to interface a PS2 keyboard is already discussed in a previous project on how to interface the PS2 keyboard with the Arduino.
As the user types the number to which the SMS needs to be sent the code reads those letters from the keyboard and directly sends those numbers to the GSM module using the serial communication functions. Once the user presses the ENETR key the code stop reading from the keyboard for a while and sends the string ““r” which forms the part of the message sending command before the actual text. The code then waits for the user to enter the SMS text. Once the user starts typing the text on the keyboard the Arduino again redirect the letters to the GSM module till the user presses the ENETR key again. Once the ENETER key is pressed the code again stops reading from the keyboard and sends the value equivalent to the <CTRL+Z> to the GSM module to complete the message sending command.
Try to send the command using the PC with the help of any serial monitoring software and make sure that the module is sending message to the specified number. Then one can verify and upload the code which can send the same commands to the Arduino board as explained in the project how to get started with the Arduino. Once the board is reset after successfully uploading the code the Arduino sends the same command to the GSM module enabling it to send SMS to the number specified in the code.
Make sure that the GSM module has been turned on at least 2 minutes before the Arduino board start sending the commands so that the GSM establish a communication with the cellular network corresponding to the SIM card inserted in it.
Project Source Code
### /*============================ EG LABS ===================================// Demonstration of how to use a ps2keyboard to type and send SMS using GSM The circuit: LCD: * LCD RS pin to digital pin 12 * LCD Enable pin to digital pin 11 * LCD D4 pin to digital pin 7 * LCD D5 pin to digital pin 6 * LCD D6 pin to digital pin 5 * LCD D7 pin to digital pin 4 * LCD R/W pin to ground * 10K resistor: * ends to +5V and ground * wiper to LCD pin 3 * LED anode attached to digital output 9 * LED cathode attached to ground through a 1K resistor KEYBOARD: DATA PIN TO PIN NUMBER 8 CLOCK PIN TO PIN NUMBER 3 GSM: RX PIN OF GSM TO TX0 PIN OF ARDUINO SHORT THE GROUND PINS OF ARDUINO AND GSM ============================== EG LABS ===================================*/ #include "PS2Keyboard.h" #include <LiquidCrystal.h> // initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 7, 6, 5, 4); #define DATA_PIN 8 PS2Keyboard keyboard; // give the pin a name: int led = 9; char dat = 0; void setup() { pinMode(9, OUTPUT); lcd.begin(16, 2); lcd.print("ENGINEERS GARAGE"); lcd.setCursor(0, 1); lcd.print(" SMS TX "); delay(3000); lcd.clear(); keyboard.begin(DATA_PIN); // initialize the PS2 keyboard // initialize the led pin as an output. pinMode(led, OUTPUT); // start serial port at 9600 bps Serial.begin(9600); // wait for a while till the serial port is ready delay(100); Serial.print("AT+CMGS="); Serial.print('"'); lcd.clear(); lcd.print("No: "); while(1) { if(keyboard.available()) // check if there is any data coming from the keyboard { dat = keyboard.read(); // read the data from the keyboard if(dat == 'n') break; else; Serial.write(dat); lcd.write(dat); }else; } Serial.print('"'); Serial.print('r'); lcd.setCursor(0, 1); while(1) { if(keyboard.available()) // check if there is any data coming from the keyboard { dat = keyboard.read(); // read the data from the keyboard if(dat == 'n') break; else; Serial.write(dat); lcd.write(dat); }else; } Serial.write(26); lcd.clear(); lcd.print("Sending ... "); } void loop() { digitalWrite(led, HIGH); delay(1000); digitalWrite(led, LOW); delay(1000); } ###
Project Source Code
### /* PS2Keyboard.cpp - PS2Keyboard library Copyright (c) 2007 Free Software Foundation. All right reserved. Written by Christian Weichel <[email protected]> ** Modified for use beginning with Arduino 13 by L. Abraham Smith, <[email protected]> * ** Modified to include: shift, alt, caps_lock, caps_lock light, and hot-plugging a kbd * ** by Bill Oldfield 22/7/09 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include "Arduino.h" #include "PS2Keyboard.h" #include "binary.h" typedef uint8_t boolean; typedef uint8_t byte; /* * I do know this is so uncool, but I just don't see a way arround it * REALLY BAD STUFF AHEAD * * The variables are used for internal status management of the ISR. The're * not kept in the object instance because the ISR has to be as fast as anyhow * possible. So the overhead of a CPP method call is to be avoided. * * PLEASE DO NOT REFER TO THESE VARIABLES IN YOUR CODE AS THEY MIGHT VANISH SOME * HAPPY DAY. */ int ps2Keyboard_DataPin; byte ps2Keyboard_CurrentBuffer; volatile byte ps2Keyboard_CharBuffer; volatile byte ps2Keyboard_BufferPos; // variables used to remember information about key presses volatile bool ps2Keyboard_shift; // indicates shift key is pressed volatile bool ps2Keyboard_ctrl; // indicates the ctrl key is pressed volatile bool ps2Keyboard_alt; // indicates the alt key is pressed volatile bool ps2Keyboard_extend; // remembers a keyboard extended char received volatile bool ps2Keyboard_release; // distinguishes key presses from releases volatile bool ps2Keyboard_caps_lock; // remembers shift lock has been pressed // vairables used in sending command bytes to the keyboard, eg caps_lock light volatile boolean cmd_in_progress; volatile int cmd_count; byte cmd_value; volatile byte cmd_ack_value; byte cmd_parity; volatile boolean cmd_ack_byte_ok; // sending command bytes to the keybaord needs proper parity (otherwise the keyboard // just asks you to repeat the byte) byte odd_parity(byte val) { int i, count = 1; // start with 0 for even parity for (i=0; i<8; i++) { if (val&1) count++; val = val>>1; } return count & 1; // bottom bit of count is parity bit } void kbd_send_command(byte val) { // stop interrupt routine from receiving characters so that we can use it // to send a byte cmd_in_progress = true; cmd_count = 0; // set up the byte to shift out and initialise the ack bit cmd_value = val; cmd_ack_value = 1; // the kbd will clear this bit on receiving the byte cmd_parity = odd_parity(val); // set the data pin as an output, ready for driving digitalWrite(ps2Keyboard_DataPin, HIGH); pinMode(ps2Keyboard_DataPin, OUTPUT); // drive clock pin low - this is going to generate the first // interrupt of the shifting out process pinMode(PS2_INT_PIN, OUTPUT); digitalWrite(PS2_INT_PIN, LOW); // wait at least one clock cycle (in case the kbd is mid transmission) delayMicroseconds(60); // set up the 0 start bit digitalWrite(ps2Keyboard_DataPin, LOW); // let go of clock - the kbd takes over driving the clock from here digitalWrite(PS2_INT_PIN, HIGH); pinMode(PS2_INT_PIN, INPUT); // wait for interrupt routine to shift out byte, parity and receive ack bit while (cmd_ack_value!=0) ; // switch back to the interrupt routine receiving characters from the kbd cmd_in_progress = false; } void PS2Keyboard::reset() { kbd_send_command(0xFF); // send the kbd reset code to the kbd: 3 lights // should flash briefly on the kbd // reset all the global variables ps2Keyboard_CurrentBuffer = 0; ps2Keyboard_CharBuffer = 0; ps2Keyboard_BufferPos = 0; ps2Keyboard_shift = false; ps2Keyboard_ctrl = false; ps2Keyboard_alt = false; ps2Keyboard_extend = false; ps2Keyboard_release = false; ps2Keyboard_caps_lock = false; cmd_in_progress = false; cmd_count = 0; cmd_value = 0; cmd_ack_value = 1; } // val : bit_2=caps_lock, bit_1=num_lock, bit_0=scroll_lock void kbd_set_lights(byte val) { // When setting the lights with the 0xED command the keyboard responds // with an "ack byte", 0xFA. This is NOT the same as the "ack bit" that // follows the succesful shifting of each command byte. See this web // page for a good description of all this: // http://www.beyondlogic.org/keyboard/keybrd.htm cmd_ack_byte_ok = false; // initialise the ack byte flag kbd_send_command(0xED); // send the command byte while (!cmd_ack_byte_ok) ; // ack byte from keyboard sets this flag kbd_send_command(val); // now send the data } // The ISR for the external interrupt // This may look like a lot of code for an Interrupt routine, but the switch // statements are fast and the path through the routine is only ever a few // simple lines of code. void ps2interrupt (void) { int value = digitalRead(ps2Keyboard_DataPin); // This is the code to send a byte to the keyboard. Actually its 12 bits: // a start bit, 8 data bits, 1 parity, 1 stop bit, 1 ack bit (from the kbd) if (cmd_in_progress) { cmd_count++; // cmd_count keeps track of the shifting switch (cmd_count) { case 1: // start bit digitalWrite(ps2Keyboard_DataPin,LOW); break; case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: // data bits to shift digitalWrite(ps2Keyboard_DataPin,cmd_value&1); cmd_value = cmd_value>>1; break; case 10: // parity bit digitalWrite(ps2Keyboard_DataPin,cmd_parity); break; case 11: // stop bit // release the data pin, so stop bit actually relies on pull-up // but this ensures the data pin is ready to be driven by the kbd for // for the next bit. digitalWrite(ps2Keyboard_DataPin, HIGH); pinMode(ps2Keyboard_DataPin, INPUT); break; case 12: // ack bit - driven by the kbd, so we read its value cmd_ack_value = digitalRead(ps2Keyboard_DataPin); cmd_in_progress = false; // done shifting out } return; // don't fall through to the receive section of the ISR } // receive section of the ISR // shift the bits in if(ps2Keyboard_BufferPos > 0 && ps2Keyboard_BufferPos < 11) { ps2Keyboard_CurrentBuffer |= (value << (ps2Keyboard_BufferPos - 1)); } ps2Keyboard_BufferPos++; // keep track of shift-in position if(ps2Keyboard_BufferPos == 11) { // a complete character received switch (ps2Keyboard_CurrentBuffer) { case 0xF0: { // key release char ps2Keyboard_release = true; ps2Keyboard_extend = false; break; } case 0xFA: { // command acknowlegde byte cmd_ack_byte_ok = true; break; } case 0xE0: { // extended char set ps2Keyboard_extend = true; break; } case 0x12: // left shift case 0x59: { // right shift ps2Keyboard_shift = ps2Keyboard_release? false : true; ps2Keyboard_release = false; break; } case 0x11: { // alt key (right alt is extended 0x11) ps2Keyboard_alt = ps2Keyboard_release? false : true; ps2Keyboard_release = false; break; } case 0x14: { // ctrl key (right ctrl is extended 0x14) ps2Keyboard_ctrl = ps2Keyboard_release? false : true; ps2Keyboard_release = false; break; } case 0x58: { // caps lock key if (!ps2Keyboard_release) { ps2Keyboard_caps_lock = ps2Keyboard_caps_lock? false : true; // allow caps lock code through to enable light on and off ps2Keyboard_CharBuffer = ps2Keyboard_CurrentBuffer; } else { ps2Keyboard_release = false; } break; } default: { // a real key if (ps2Keyboard_release) { // although ignore if its just released ps2Keyboard_release = false; } else { // real keys go into CharBuffer ps2Keyboard_CharBuffer = ps2Keyboard_CurrentBuffer; } } } ps2Keyboard_CurrentBuffer = 0; ps2Keyboard_BufferPos = 0; } } PS2Keyboard::PS2Keyboard() { // nothing to do here } void PS2Keyboard::begin(int dataPin) { // Prepare the global variables ps2Keyboard_DataPin = dataPin; ps2Keyboard_CurrentBuffer = 0; ps2Keyboard_CharBuffer = 0; ps2Keyboard_BufferPos = 0; ps2Keyboard_shift = false; ps2Keyboard_ctrl = false; ps2Keyboard_alt = false; ps2Keyboard_extend = false; ps2Keyboard_release = false; ps2Keyboard_caps_lock = false; cmd_in_progress = false; cmd_count = 0; cmd_value = 0; cmd_ack_value = 1; // initialize the pins pinMode(PS2_INT_PIN, INPUT); digitalWrite(PS2_INT_PIN, HIGH); pinMode(dataPin, INPUT); digitalWrite(dataPin, HIGH); attachInterrupt(1, ps2interrupt, FALLING); #if 0 // Global Enable INT1 interrupt EIMSK |= ( 1 << INT1); // Falling edge triggers interrupt EICRA |= (0 << ISC10) | (1 << ISC11); #endif } bool PS2Keyboard::available() { return ps2Keyboard_CharBuffer != 0; } // This routine allows a calling program to see if other other keys are held // down when a character is received: ie <ctrl>, <alt>, <shift> or <shift_lock> // Note that this routine must be called after available() has returned true, // but BEFORE read(). The read() routine clears the buffer and allows another // character to be received so these bits can change anytime after the read(). byte PS2Keyboard::read_extra() { return (ps2Keyboard_caps_lock<<3) | (ps2Keyboard_shift<<2) | (ps2Keyboard_alt<<1) | ps2Keyboard_ctrl; } byte PS2Keyboard::read() { byte result; // read the raw data from the keyboard result = ps2Keyboard_CharBuffer; // Use a switch for the code to character conversion. // This is fast and actually only uses 4 bytes per simple line switch (result) { case 0x1C: result = 'a'; break; case 0x32: result = 'b'; break; case 0x21: result = 'c'; break; case 0x23: result = 'd'; break; case 0x24: result = 'e'; break; case 0x2B: result = 'f'; break; case 0x34: result = 'g'; break; case 0x33: result = 'h'; break; case 0x43: result = 'i'; break; case 0x3B: result = 'j'; break; case 0x42: result = 'k'; break; case 0x4B: result = 'l'; break; case 0x3A: result = 'm'; break; case 0x31: result = 'n'; break; case 0x44: result = 'o'; break; case 0x4D: result = 'p'; break; case 0x15: result = 'q'; break; case 0x2D: result = 'r'; break; case 0x1B: result = 's'; break; case 0x2C: result = 't'; break; case 0x3C: result = 'u'; break; case 0x2A: result = 'v'; break; case 0x1D: result = 'w'; break; case 0x22: result = 'x'; break; case 0x35: result = 'y'; break; case 0x1A: result = 'z'; break; // note that caps lock only used on a-z case 0x41: result = ps2Keyboard_shift? '<' : ','; break; case 0x49: result = ps2Keyboard_shift? '>' : '.'; break; case 0x4A: result = ps2Keyboard_shift? '?' : '/'; break; case 0x54: result = ps2Keyboard_shift? '{' : '['; break; case 0x5B: result = ps2Keyboard_shift? '}' : ']'; break; case 0x4E: result = ps2Keyboard_shift? '_' : '-'; break; case 0x55: result = ps2Keyboard_shift? '+' : '='; break; case 0x29: result = ' '; break; case 0x45: result = ps2Keyboard_shift? ')' : '0'; break; case 0x16: result = ps2Keyboard_shift? '!' : '1'; break; case 0x1E: result = ps2Keyboard_shift? '@' : '2'; break; case 0x26: result = ps2Keyboard_shift? 'Ă‚£' : '3'; break; case 0x25: result = ps2Keyboard_shift? '$' : '4'; break; case 0x2E: result = ps2Keyboard_shift? '%' : '5'; break; case 0x36: result = ps2Keyboard_shift? '^' : '6'; break; case 0x3D: result = ps2Keyboard_shift? '&' : '7'; break; case 0x3E: result = ps2Keyboard_shift? '*' : '8'; break; case 0x46: result = ps2Keyboard_shift? '(' : '9'; break; case 0x0D: result = 't'; break; case 0x5A: result = 'n'; break; case 0x66: result = PS2_KC_BKSP; break; case 0x69: result = ps2Keyboard_extend? PS2_KC_END : '1'; break; case 0x6B: result = ps2Keyboard_extend? PS2_KC_LEFT : '4'; break; case 0x6C: result = ps2Keyboard_extend? PS2_KC_HOME : '7'; break; case 0x70: result = ps2Keyboard_extend? PS2_KC_INS : '0'; break; case 0x71: result = ps2Keyboard_extend? PS2_KC_DEL : '.'; break; case 0x72: result = ps2Keyboard_extend? PS2_KC_DOWN : '2'; break; case 0x73: result = '5'; break; case 0x74: result = ps2Keyboard_extend? PS2_KC_RIGHT : '6'; break; case 0x75: result = ps2Keyboard_extend? PS2_KC_UP : '8'; break; case 0x76: result = PS2_KC_ESC; break; case 0x79: result = '+'; break; case 0x7A: result = ps2Keyboard_extend? PS2_KC_PGDN : '3'; break; case 0x7B: result = '-'; break; case 0x7C: result = '*'; break; case 0x7D: result = ps2Keyboard_extend? PS2_KC_PGUP : '9'; break; case 0x58: // setting the keyboard lights is done here. Ideally it would be done // in the interrupt routine itself and the key codes associated wth // caps lock key presses would never be passed on as characters. // However it would make the interrupt routine very messy with lots // of extra state associated with the control of a caps_lock // key code causing a cmd byte to transmit, causing an ack_byte to // be received, then a data byte to transmit. Much easier done here. // The downside, however, is that the light going on or off at the // right time relies on the calling program to be checking for // characters on a regular basis. If the calling program stops // polling for characters at any point pressing the caps lock key // will not change the state of the caps lock light while polling // is not happening. result = ps2Keyboard_caps_lock? PS2_KC_CLON : PS2_KC_CLOFF; if (ps2Keyboard_caps_lock) kbd_set_lights(4); else kbd_set_lights(0); break; // Reset the shift counter for unexpected values, to get back into sink // This allows for hot plugging a keyboard in and out default: delay(500); // but wait a bit in case part way through a shift ps2Keyboard_BufferPos = 0; ps2Keyboard_shift = false; ps2Keyboard_ctrl = false; ps2Keyboard_alt = false; ps2Keyboard_extend = false; ps2Keyboard_release = false; ps2Keyboard_caps_lock = false; } // end switch(result) // shift a-z chars here (less code than in the switch statement) if (((result>='a') && (result<='z')) && ((ps2Keyboard_shift && !ps2Keyboard_caps_lock) || (!ps2Keyboard_shift && ps2Keyboard_caps_lock))) { result = result + ('A'-'a'); } // done with the character ps2Keyboard_CharBuffer = 0; return(result); } ************Header File************* /* PS2Keyboard.h - PS2Keyboard library Copyright (c) 2007 Free Software Foundation. All right reserved. Written by Christian Weichel <[email protected]> ** Modified for use with Arduino 13 by L. Abraham Smith, <[email protected]> * ** Modified to include: shift, alt, caps_lock and caps_lock light by Bill Oldfield * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PS2Keyboard_h #define PS2Keyboard_h #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> /* * PS2 keyboard "make" codes to check for certain keys. */ // Give these codes that aren't used by anything else // Making all the control key codes above 0x80 makes it simple to check for // printable characters at the calling level. #define PS2_KC_BKSP 0x80 #define PS2_KC_UP 0x81 #define PS2_KC_DOWN 0x82 #define PS2_KC_LEFT 0x83 #define PS2_KC_RIGHT 0x84 #define PS2_KC_PGDN 0x85 #define PS2_KC_PGUP 0x86 #define PS2_KC_END 0x87 #define PS2_KC_HOME 0x88 #define PS2_KC_INS 0x89 #define PS2_KC_DEL 0x8A #define PS2_KC_ESC 0x8B #define PS2_KC_CLON 0x8C // caps_lock on #define PS2_KC_CLOFF 0x8D // caps_lock off #include "binary.h" typedef uint8_t boolean; typedef uint8_t byte; /* * This PIN is hardcoded in the init routine later on. If you change this * make sure you change the interrupt initialization as well. */ #define PS2_INT_PIN 3 /** * Purpose: Provides an easy access to PS2 keyboards * Author: Christian Weichel */ class PS2Keyboard { private: int m_dataPin; byte m_charBuffer; public: /** * This constructor does basically nothing. Please call the begin(int) * method before using any other method of this class. */ PS2Keyboard(); /** * Starts the keyboard "service" by registering the external interrupt. * setting the pin modes correctly and driving those needed to high. * The propably best place to call this method is in the setup routine. */ void begin(int dataPin); /** * Returns true if there is a char to be read, false if not. */ bool available(); /** * Sends a reset command to the keyboard and re-initialises all the control * variables within the PS2Keybaord code. */ void reset(); /** * Returns the char last read from the keyboard. If the user has pressed two * keys between calls to this method, only the later one will be availble. Once * the char has been read, the buffer will be cleared. * If there is no char availble, 0 is returned. */ byte read(); /** * Returns the status of the <ctrl> key, the <alt> key, the <shift> key and the * caps_lock state. Note that shift and caps_lock are handled within the * Ps2Keyboard code (and the return value from read() is already modified), but * being able to read them here may be useful. * This routine is optional BUT MUST ONLY be read after available() has returned * true and BEFORE read() is called to retrieve the character. Reading it after * the call to read() will return unpredictable values. */ byte read_extra(); }; #endif ###
Circuit Diagrams
Project Components
Project Video
Filed Under: Arduino Projects
Filed Under: Arduino Projects
Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.