├── ATcommands.h ├── README.md ├── LICENSE.txt ├── Examples └── sendATcommands │ └── sendATcommands.ino └── ATcommands.cpp /ATcommands.h: -------------------------------------------------------------------------------- 1 | #ifndef ATcommands_h 2 | #define ATcommands_h 3 | 4 | #include "Arduino.h" 5 | 6 | #define default_pulse_ms 100 7 | #define default_timeout_ms 1000 8 | 9 | 10 | class ATcommands { 11 | public: 12 | ATcommands(int8_t rst, bool newline = false); 13 | void begin(Stream &port); 14 | void reset(uint8_t pulse, uint16_t duration = default_pulse_ms); 15 | bool sendBlindCommand(char *command); 16 | bool sendCommand(char *command, uint16_t timeout = default_timeout_ms); 17 | bool sendCommand(char *command, char *reply, uint16_t timeout = default_timeout_ms); 18 | 19 | private: 20 | int8_t _rst; 21 | bool newline = false; 22 | char replybuffer[255]; 23 | unsigned long timer; 24 | Stream *mySerial; 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino IDE AT Command Library 2 | 3 | ## Description 4 | This library is useful for projects in which commands (like AT or ASCII commands) are sent from a microcontroller to a module via UART. This library supports software serial and hardware serial and can check for desired responses from the target module. 5 | 6 | ## Usage 7 | To install the library in Arduino IDE, follow the instructions below: 8 | - Click the "Clone or Download" button and click "Download ZIP" 9 | - Click on the ZIP file after it finishes downloading and extrac the folder to your Arduino sketchbook directory. By default this is Documents/Arduino/libraries 10 | - Alternatively, open the Arduino IDE and navigate to Sketch -> Include Library -> Include .ZIP Library and restart Arduino IDE 11 | - That's it! Now in Arduino IDE go to File -> Examples -> ATcommands -> Examples to load the example sketch 12 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Botletics LLC. All rights reserved. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Examples/sendATcommands/sendATcommands.ino: -------------------------------------------------------------------------------- 1 | /* This code is an example of how to use the AT command library to 2 | * send AT commands (or ASCII commands) to a module via UART (TX/RX) 3 | * using software or hardware serial. The commands can be set up to 4 | * check for a specified reply from the module as well as a timeout. 5 | * 6 | * Author: Timothy Woo (botletics.com) 7 | * Last Modified: 10/20/2017 8 | */ 9 | 10 | #include "ATcommands.h" 11 | #include 12 | 13 | #define MCU_RX 9 // Remember MCU RX connects to module TX and vice versa 14 | #define MCU_TX 10 15 | #define RST 4 // MCU pin to control module reset 16 | 17 | SoftwareSerial moduleSS = SoftwareSerial(MCU_RX, MCU_TX); // MCU RX, TX 18 | SoftwareSerial *moduleSerial = &moduleSS; 19 | 20 | // Hardware serial is also possible! 21 | // HardwareSerial *moduleSerial = &Serial1; 22 | 23 | ATcommands module = ATcommands(RST, false); // Use "false" if you don't want AT commands with newline, "true" otherwise 24 | 25 | void setup() { 26 | Serial.begin(115200); 27 | 28 | moduleSerial->begin(9600); // Verify your module's baud rate 29 | module.begin(*moduleSerial); 30 | 31 | // Reset module if needed. This example pulses the reset pin low for 10ms. 32 | // If left out, the pulse duration is 100ms by default. 33 | module.reset(LOW, 10); // module.reset(HIGH/LOW, pulseDuration) 34 | 35 | // Blindly send command without checking for reply or timeout 36 | module.sendBlindCommand("AT"); 37 | delay(1000); // May want to include a small delay depending on what module you're using 38 | 39 | // Send command with timeout but without checking for specific response. Will return false if no reply 40 | if (!module.sendCommand("AT", 1000)) Serial.println(F("Command failed!")); 41 | delay(1000); 42 | 43 | // If you leave out the timeout value it defaults to 1000ms, which is usually good enough for most commands 44 | if (!module.sendCommand("AT")) Serial.println(F("Command failed!")); 45 | delay(1000); 46 | 47 | // Send command with timeout and check if module's response matches the desired 48 | if (!module.sendCommand("AT", "OK", 1000)) Serial.println(F("Command failed!")); 49 | } 50 | 51 | void loop() { 52 | // Nothing here 53 | } 54 | -------------------------------------------------------------------------------- /ATcommands.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ATcommands.h" 3 | 4 | ATcommands::ATcommands(int8_t rst, bool lineEnding) { 5 | pinMode(rst, OUTPUT); 6 | 7 | _rst = rst; 8 | mySerial = 0; 9 | newline = lineEnding; 10 | } 11 | 12 | void ATcommands::begin(Stream &port) { 13 | mySerial = &port; 14 | } 15 | 16 | void ATcommands::reset(uint8_t pulse, uint16_t duration) { 17 | if (pulse == LOW) { 18 | digitalWrite(_rst, HIGH); 19 | delay(10); 20 | digitalWrite(_rst, LOW); 21 | delay(duration); 22 | digitalWrite(_rst, HIGH); 23 | } 24 | else if (pulse == HIGH) { 25 | digitalWrite(_rst, LOW); 26 | delay(10); 27 | digitalWrite(_rst, HIGH); 28 | delay(duration); 29 | digitalWrite(_rst, LOW); 30 | } 31 | } 32 | 33 | bool ATcommands::sendBlindCommand(char *command) { 34 | Serial.print(F("\t---> ")); Serial.println(command); 35 | if (newline) mySerial->println(command); 36 | else mySerial->print(command); 37 | } 38 | 39 | bool ATcommands::sendCommand(char *command, uint16_t timeout) { 40 | while(mySerial->available()) mySerial->read(); // Clear input buffer 41 | 42 | Serial.print(F("\t---> ")); Serial.println(command); 43 | if (newline) mySerial->println(command); 44 | else mySerial->print(command); 45 | 46 | bool gotReply = false; 47 | timer = millis(); 48 | 49 | while (!gotReply && millis() - timer < timeout) { 50 | if (mySerial->available()) gotReply = true; 51 | } 52 | 53 | if (gotReply) return true; 54 | else return false; 55 | } 56 | 57 | bool ATcommands::sendCommand(char *command, char *reply, uint16_t timeout) { 58 | while(mySerial->available()) mySerial->read(); // Clear input buffer 59 | 60 | Serial.print(F("\t---> ")); Serial.println(command); 61 | if (newline) mySerial->println(command); 62 | else mySerial->print(command); 63 | 64 | uint8_t idx = 0; 65 | bool replyMatch = false; 66 | timer = millis(); 67 | 68 | while (!replyMatch && millis() - timer < timeout) { 69 | if (mySerial->available()) { 70 | replybuffer[idx] = mySerial->read(); 71 | idx++; 72 | // if (strstr(replybuffer, reply) != NULL) replyMatch = true; // Only checks if desired reply is inside replybuffer 73 | if (strcmp(replybuffer, reply) == 0) replyMatch = true; // This means the reply must start with the desired reply to be successful 74 | } 75 | } 76 | 77 | Serial.print(F("\t<--- ")); Serial.println(replybuffer); 78 | 79 | if (replyMatch) return true; 80 | else return false; 81 | } 82 | --------------------------------------------------------------------------------