├── README.md ├── RX_message.ino ├── RX_minimal.ino ├── TX_message.ino └── TX_minimal.ino /README.md: -------------------------------------------------------------------------------- 1 | # arduinoPAGERcc1101 2 | 3 | A Arduino UNO 80 character pager project with 80 character screen using cc1101 RF module to transmit message. 4 | 5 | wiring up the RF module. Generally the CC1101 RF modules are 3.3v NOT 5V so logic level translator is needed with arduino 6 | UNO 7 | 8 | I got wiring info here: 9 | 10 | http://labalec.fr/erwan/?p=497 11 | 12 | We are using I2C version of 80 character screen to save pins on arduino for SPI connectiomn to RF module ! 13 | 14 | 15 | Using the cc1101 RF module we can send 4 lines of text in 4 20 byte packets to another arduino 16 | 17 | we are using the Liquid crystal library and I2C interface for screen 18 | 19 | we are using the PANSTAMP library for the CC1101 module with SPI 20 | 21 | We will be adding a USB host for keyboard next ( still looking for a smaller qwerty blackberry style keyboard instead ! ) 22 | 23 | Also will be writing some kind of menu system for creating / sending messages.. 24 | 25 | I will post a full wiring diagram when we work out a satifactory keyboard! currently working on a USB host for any qwerty 26 | keyboard. this is too large to use as a pager !! 27 | 28 | currently the PAGER message is manually entered into the array in the code :( 29 | 30 | Instructions. 31 | 32 | 1, wire up 2 arduino Uno's with 80 character screens with I2C 33 | 2, connect CC1101 RF modules with SPI 34 | 3, get Liquidcrystal library 35 | 4, get PanStamp Library ( correct version ) will upload here soon 36 | 5, load TX_message.ino code on TX arduino 37 | 6, load RX_message.ino code on RX arduino 38 | 39 | 7, change text in array to whatever you like? ( if longer than 80 characters I guess it wont get there ! ) 40 | 41 | Text is sent in 4 packets.. one line at a time. if the reciever is switched on as TX arduino is mid transmit it will possibley recieve line 2 , 3 or 4 before line 1 ? re transmit interval set by simple delay 42 | 43 | 44 | things to do; 45 | 46 | store and recall messages on flash memeory ? add message number variable ? 47 | 48 | add PA to cc1101 for longer range ? 49 | 50 | find small qwerty blackberry style keyboard with arduino library ? 51 | 52 | build menu system ( store send resend time limits etc ) 53 | 54 | * in the long future relay messages to next recipient? 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /RX_message.ino: -------------------------------------------------------------------------------- 1 | #include "EEPROM.h" 2 | #include "cc1101.h" 3 | #include // I2C arduino library ( comes with arduino ) 4 | #include 5 | 6 | // set the LCD address to 0x27 for a 20 chars 4 line display 7 | // Set the pins on the I2C chip used for LCD connections: 8 | // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol 9 | LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address 10 | 11 | 12 | // The connection to the hardware chip CC1101 the RF Chip 13 | CC1101 cc1101; 14 | 15 | byte b; 16 | byte i; 17 | byte syncWord = 199; 18 | long counter=0; 19 | byte packet_num=1; 20 | byte chan=0; 21 | 22 | 23 | 24 | // a flag that a wireless packet has been received 25 | boolean packetAvailable = false; 26 | 27 | 28 | /* Handle interrupt from CC1101 (INT0) gdo0 on pin2 */ 29 | void cc1101signalsInterrupt(void){ 30 | // set the flag that a package is available 31 | packetAvailable = true; 32 | } 33 | 34 | // SETUP HERE 35 | 36 | void setup() 37 | { 38 | lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines, turn on backlight 39 | lcd.clear(); 40 | 41 | // initialize the RF Chip 42 | cc1101.init(); 43 | cc1101.setSyncWord(&syncWord, false); 44 | cc1101.setCarrierFreq(CFREQ_433); 45 | cc1101.disableAddressCheck(); //if not specified, will only display "packet received" 46 | //cc1101.setTxPowerAmp(PA_LowPower); 47 | 48 | 49 | attachInterrupt(0, cc1101signalsInterrupt, FALLING); // need to find out what this does !! BB, initialise rf? 50 | lcd.setCursor(0,1); 51 | lcd.print("..initialized.."); 52 | delay(500); 53 | lcd.clear(); 54 | } 55 | 56 | void recieve_message() 57 | { 58 | // BLINK Packet Recieved if wanted 59 | if(packetAvailable){ 60 | detachInterrupt(0); 61 | // clear the flag 62 | packetAvailable = false; 63 | 64 | CCPACKET packet; 65 | 66 | if(cc1101.receiveData(&packet) > 0){ 67 | if(!packet.crc_ok) { 68 | lcd.setCursor(0,3); 69 | lcd.print("crc not ok"); 70 | 71 | } 72 | // if packet OK print 73 | if(packet.length > 0){ 74 | 75 | lcd.setCursor(0,packet.data[0]-1); 76 | { 77 | for( int x = 1 ; x < 21 ; ++x ){ 78 | lcd.write(packet.data[x]); 79 | } 80 | lcd.setCursor(19,3); 81 | lcd.print(packet.data[0]); 82 | 83 | }}}} 84 | // Enable wireless reception interrupt 85 | attachInterrupt(0, cc1101signalsInterrupt, FALLING); 86 | } 87 | 88 | 89 | void loop() 90 | { 91 | recieve_message(); // recieve message mode in ON !! 92 | } 93 | -------------------------------------------------------------------------------- /RX_minimal.ino: -------------------------------------------------------------------------------- 1 | #include "EEPROM.h" 2 | #include "cc1101.h" 3 | #include // I2C arduino library ( comes with arduino ) 4 | #include 5 | 6 | // set the LCD address to 0x27 for a 20 chars 4 line display 7 | // Set the pins on the I2C chip used for LCD connections: 8 | // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol 9 | LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address 10 | 11 | 12 | // The connection to the hardware chip CC1101 the RF Chip 13 | CC1101 cc1101; 14 | 15 | byte b; 16 | byte i; 17 | byte syncWord = 199; 18 | long counter=0; 19 | byte chan=0; 20 | 21 | // a flag that a wireless packet has been received 22 | boolean packetAvailable = false; 23 | 24 | 25 | /* Handle interrupt from CC1101 (INT0) gdo0 on pin2 */ 26 | void cc1101signalsInterrupt(void){ 27 | // set the flag that a package is available 28 | packetAvailable = true; 29 | } 30 | 31 | // SETUP HERE 32 | 33 | void setup() 34 | { 35 | lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines, turn on backlight 36 | lcd.clear(); 37 | 38 | // initialize the RF Chip 39 | cc1101.init(); 40 | cc1101.setSyncWord(&syncWord, false); 41 | cc1101.setCarrierFreq(CFREQ_433); 42 | cc1101.disableAddressCheck(); //if not specified, will only display "packet received" 43 | //cc1101.setTxPowerAmp(PA_LowPower); 44 | 45 | 46 | attachInterrupt(0, cc1101signalsInterrupt, FALLING); // need to find out what this does !! BB, initialise rf? 47 | lcd.setCursor(0,1); 48 | lcd.print("device initialized"); 49 | delay(800); 50 | lcd.clear(); 51 | } 52 | 53 | void loop() 54 | { 55 | // BLINK Packet Recieved if wanted 56 | if(packetAvailable){ 57 | detachInterrupt(0); 58 | // clear the flag 59 | packetAvailable = false; 60 | 61 | CCPACKET packet; 62 | 63 | if(cc1101.receiveData(&packet) > 0){ 64 | if(!packet.crc_ok) { 65 | lcd.setCursor(0,3); 66 | lcd.print("crc not ok"); 67 | delay(200); 68 | lcd.setCursor(0,3); 69 | lcd.print(" "); 70 | } 71 | 72 | if(packet.length > 0){ 73 | 74 | lcd.setCursor(0,0); 75 | lcd.print(packet.data[0]); 76 | lcd.setCursor(4,0); 77 | lcd.print(":A packets RX"); 78 | lcd.blink(); 79 | 80 | lcd.setCursor(0,1); 81 | lcd.print(packet.data[1]); 82 | lcd.setCursor(4,1); 83 | lcd.print(":B packets RX"); 84 | lcd.blink(); 85 | 86 | } 87 | } 88 | } 89 | // Enable wireless reception interrupt 90 | attachInterrupt(0, cc1101signalsInterrupt, FALLING); 91 | } 92 | 93 | -------------------------------------------------------------------------------- /TX_message.ino: -------------------------------------------------------------------------------- 1 | #include "EEPROM.h" 2 | #include "cc1101.h" //cc1101.flushTxFifo (); // NOT SURE if ever NEEDED? 3 | #include // I2C arduino library ( comes with arduino ) 4 | #include 5 | 6 | // set the LCD address to 0x27 for a 20 chars 4 line display 7 | // Set the pins on the I2C chip used for LCD connections: 8 | // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol 9 | LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address 10 | 11 | CC1101 cc1101; 12 | 13 | // counter to get increment in each loop 14 | byte counter; 15 | byte b; 16 | byte syncWord = 199; // sender and reciever must have same!!! like ip address? 17 | byte packet_num = 1; 18 | //make the message array and make it into HEX code so I can transmit??? 19 | // char pagertext[2] = {"A"}; make an array ?? 20 | 21 | char arrayA[81] = { " alright! welcome to the begining of the awsome long ranger pager project :) !!!" }; 22 | byte arrayB[81] = {}; 23 | 24 | // SETUP HERE 25 | void setup() 26 | { 27 | lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines, turn on backlight 28 | 29 | // load char arrayA into BYTE arrayB 30 | 31 | { 32 | for( int i = 1 ; i < 81 ; ++i ){ 33 | arrayB[ i ] = arrayA[ i ]; 34 | } 35 | } 36 | 37 | counter=1; // start counter at zero ! 38 | 39 | // initialize the RF Chip 40 | lcd.print("initializing......"); 41 | cc1101.init(); 42 | cc1101.setSyncWord(&syncWord, false); 43 | cc1101.setCarrierFreq(CFREQ_433); 44 | cc1101.disableAddressCheck(); 45 | cc1101.setTxPowerAmp(PA_LongDistance); // if you want HIGH POWER 46 | delay(500); 47 | lcd.clear(); 48 | } 49 | // cc1101.flushTxFifo (); // is this needed??? 50 | /// end void setup 51 | 52 | 53 | 54 | // send_data() becomes a function to be used in void loop() 55 | void send_data() 56 | { 57 | CCPACKET data; 58 | data.length=21; //packet data size 59 | packet_num=counter++; // make packet_num a byte and load it with counter value 60 | data.data[0]=packet_num; // packet address 61 | 62 | 63 | // load character 'byte numbers' to packet( there are 4 packets 1 -4 defined by packet_num ) 64 | 65 | if (packet_num == 1) 66 | { 67 | for( int i = 1 ; i < 21 ; ++i ){ 68 | data.data[i]=arrayB[i]; 69 | } 70 | } 71 | 72 | if (packet_num == 2) 73 | { 74 | for( int i = 21 ; i < 41 ; ++i ){ 75 | data.data[i-20]=arrayB[i]; 76 | } 77 | } 78 | 79 | if (packet_num == 3) 80 | { 81 | for( int i = 41 ; i < 61 ; ++i ){ 82 | data.data[i-40]=arrayB[i]; 83 | } 84 | } 85 | 86 | if (packet_num == 4) 87 | { 88 | for( int i = 61 ; i < 81 ; ++i ){ 89 | data.data[i-60]=arrayB[i]; 90 | } 91 | } 92 | 93 | 94 | // print the characters from the byte char number to screen in 20 characters at a time 95 | // Print LCD screen lines 1 & 2 96 | 97 | if(cc1101.sendData(data)){ ///This sends the data ' including the packet address ? 98 | delay(20); 99 | } 100 | 101 | // print it too the LCD screen 102 | lcd.setCursor(0,packet_num-1); 103 | { 104 | for( int i = 1 ; i < 21 ; ++i ){ 105 | lcd.write(data.data[i]); 106 | } 107 | 108 | // print packet number 109 | lcd.setCursor(19,4); 110 | lcd.print(packet_num); 111 | 112 | if (counter >= 5) 113 | { 114 | counter=1; 115 | delay(10000); //wait 10 seconds between send 116 | lcd.clear(); // clear screen before each send 117 | 118 | } 119 | 120 | }} 121 | 122 | // send data with the send_data() function described above., 123 | 124 | void loop() 125 | { 126 | send_data(); 127 | delay(10); 128 | } 129 | -------------------------------------------------------------------------------- /TX_minimal.ino: -------------------------------------------------------------------------------- 1 | #include "EEPROM.h" 2 | #include "cc1101.h" //cc1101.flushTxFifo (); // NOT SURE if ever NEEDED? 3 | #include // I2C arduino library ( comes with arduino ) 4 | #include 5 | 6 | // set the LCD address to 0x27 for a 20 chars 4 line display 7 | // Set the pins on the I2C chip used for LCD connections: 8 | // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol 9 | LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address 10 | 11 | CC1101 cc1101; 12 | 13 | // counter to get increment in each loop 14 | byte counter; 15 | byte b; 16 | byte syncWord = 199; // sender and reciever must have same!!! like ip address? 17 | 18 | //LCD SCREEN SETUP 19 | 20 | // SETUP HERE 21 | void setup() 22 | { 23 | lcd.begin(20,4); // initialize the lcd for 20 chars 4 lines, turn on backlight 24 | // reset the counter 25 | counter=0; 26 | 27 | // initialize the RF Chip 28 | lcd.print("initializing..."); 29 | cc1101.init(); 30 | cc1101.setSyncWord(&syncWord, false); 31 | cc1101.setCarrierFreq(CFREQ_433); 32 | cc1101.disableAddressCheck(); 33 | cc1101.setTxPowerAmp(PA_LongDistance); // if you want HIGH POWER 34 | delay(500); 35 | lcd.clear(); 36 | } 37 | /// end void setup 38 | 39 | // send_data() becomes a function to be used in void loop() 40 | 41 | void send_data() 42 | { 43 | 44 | cc1101.flushTxFifo (); // is this needed??? 45 | 46 | CCPACKET data; 47 | data.length=2; 48 | byte blinkCount=counter++; 49 | byte blinkCount2=blinkCount*2; 50 | 51 | data.data[0]=blinkCount; 52 | data.data[1]=blinkCount2; 53 | 54 | if(cc1101.sendData(data)){ 55 | 56 | delay(1000); 57 | 58 | lcd.setCursor(0,0); 59 | lcd.print(blinkCount); 60 | lcd.setCursor(4,0); 61 | lcd.print(":A packets sent"); 62 | 63 | lcd.setCursor(0,1); 64 | lcd.print(blinkCount2); 65 | lcd.setCursor(4,1); 66 | lcd.print(":B packets sent"); 67 | lcd.blink(); 68 | 69 | }else{ 70 | lcd.setCursor(0,3); 71 | lcd.print(" sent failed :("); 72 | delay(200); 73 | lcd.setCursor(0,3); 74 | lcd.print(" "); 75 | } 76 | } 77 | 78 | // send data ( does this send all the data in state machine?? ) 79 | 80 | void loop() 81 | { 82 | send_data(); 83 | delay(2000); 84 | } 85 | --------------------------------------------------------------------------------