How to communicate with sim800c using Raspberry pi 3 in c++ - c++

My end goal is to try and send some simple data that's stored on my Raspberry pi 3 to an external server/website using a sim800c from a c++ program. I believe the easiest way to do this is to issue "AT commands" to the sim/modem however I'm struggling to do this. I can't figure out how I'm actually suppose to issue AT commands or how I can check if they're working. For testing purposes I've written some code which should send a text message to a phone number once I've gotten this working it should be fairly straight forward to figure out the AT commands to communicate with a server.
Below is an image of how I've wired everything up which I'm fairly confident is correct.
https://i.imgur.com/zysmNXE.jpg
Below is the basic c++ code that I've written using various guides, it compiles and runs in terminal however I don't get any response from the AT commands and more importantly as far as I can tell their not actually being executed. I've tried changing the fake number to my personal one but it didn't make a difference.
#include <stdio.h>
#include <string.h>
#include <wiringPi.h>
#include <wiringSerial.h>
int main ()
{
int connection;
printf("Opening connection \n");
connection = serialOpen("/dev/ttyAMA0", 9600);
delay(1000);
printf("Connection: %d\n", connection);
printf("\n");
//Set gsm to text mode
serialPuts(connection,"AT+CMGF \r\n");
delay(1000);
//Number that the message should be sent to
serialPuts(connection,"AT+CMGS=\"12345678900\"\r\n");
delay(1000);
//The message
serialPuts(connection,"Hello World");
delay(1000);
//Print ctrl+x
serialPuts(connection,"\x1A");
delay(1000);
printf("Done \n");
return 0 ;
}
As far as I can tell there are 3 likely reasons why it's not working;
A possible config/settings issue with the pi
I've wired it up incorrectly
The sim/module isn't working
I'm just not sure how to go about testing/finding what is causing the issue. If I could get my code to output the response of the AT commands after doing "serialPuts" that might help me figure out whats going on but I haven't made much luck doing that. Alternatively If anyone has an idea why the commands don't appear to be working or can provide me some ways to debug/test them that would be great.

The issue turned out just to be a simple wiring mistake.
I had wired the txd pin of the sim module to the txd pin on the raspberry pie as I was under the impression you just needed to match the pins however I didn't think/realize that the txd pin needed to go to the rxd pin instead. Changing these around allowed me to see the commands & responses being returned from the module.
To actually get the gprs working I also needed to temporarily set the pwr pin to low then high.

Related

ESP32 attempt reconnect to when network drops without halting loop (Arduino)

I have an ESP 32 collect data from a moisture sensor, which it then serves on our network. Our WiFi turns off between 1am and 6 am (because no one is using it). The ESP does not automatically try to reconnect, so it gathered data all night which I straight up can not access now.
For obvious reasons I do not want it to halt data collection when it looses connection to our network, so I can not have a loop try to reconnect. I tried this code:
void loop() {
sensor_value = analogRead(sensor_pin);
Serial.println(sensor_value);
push_value(float(sensor_value)/2047.0);
//============
//RELEVANT BIT
//============
if( WiFi.status() != WL_CONNECTED ){
//Try to recconect if connection is lost....
WiFi.disconnect();
WiFi.begin(ssid, pwd);
}
delay(second_delay*1000);
}
I've seen everyone run Wifi.disconnect() before attempting reconnecting. Is that necessary. Also does WiFi.begin() pause execution? I can't test my code right now unfortunately.
I am using the Arduino IDE and Wifi.h
And before you ask: Yes, 2047 is correct. I am running the sensor on the wrong voltage which results in about this max value.
Given that you've tagged esp8266 wifi, I'm assuming you're using that library. If so, then wifi.begin will not block execution. The library sets autoreconnect by default, so it'll automatically reconnect to the last access point when available. Any client functions will simply return an error code while disconnected. I do not know of any reason that wifi.disconnect should be called before begin.

How to connect 2 SPI devices to Arduino MkrZero

I am having a problem where I am unable to connect 2 SPI devices to my MkrZero. One device is a CAN shield and the other is an Ethernet Shield .
Both work fine on their own without the other connected but don't seem to work when both connected at the same time. This makes me think that my wiring and code is correct but something is still missing.
The CAN section initializes no matter what, execution seems to stop at the Ethernet code. But the Ethernet code works fine when the CAN wires are disconnected.
I have tried manually setting the CS pins, this doesn't do much. Even with both pins held high CAN starts up. This implies that the libraries take control of the pins.
I have read various tutorials on how to connect multiple devices with SPI but most times the devices are duplicates. My devices are different. I have connected the SPI pins exactly as I should with different CS pins for each device but the problem persists.
Here is my code
#include <CAN.h> //https://github.com/sandeepmistry/arduino-CAN
#include <MCP2515.h> //https://github.com/sandeepmistry/arduino-CAN Changes CS and Int pins from Uno to MkrZero configuration
#include <Ethernet.h>
#include <ArduinoJson.hpp>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <Losant.h>
#include <SPI.h>
//Ethernet setup
#define MQTT_MAX_TRANSFER_SIZE 80 //this was done as a result of troubleshooting
byte mac[] = { 0x2C, 0xF7, 0xF1, 0x08, 0x19, 0x2C };
IPAddress ip (192, 168, 0, 1);
EthernetClient client;
// ** Configure the Losant credentials to enable comms over mqtt **
const char* LOSANT_DEVICE_ID = "";
const char* LOSANT_ACCESS_KEY = "";
const char* LOSANT_ACCESS_SECRET = "";
LosantDevice device(LOSANT_DEVICE_ID);
// The setup() function runs once each time the micro-controller starts
void setup()
{
Serial.begin(9600);
while(!Serial) { }
Serial.println("started UART");
//pinMode(BUTTON_PIN, INPUT);
// disable SD SPI
pinMode(4,OUTPUT);
digitalWrite(4,HIGH);
//starting ethernet
Ethernet.init(6); //changing Ethernet shield software select pin to 6 since default is an SPI transfer pin
Serial.println("ethernet about to start");
while(!Ethernet.begin(mac)) {}
Serial.println("ethernet started");
while (!CAN.begin(200E3)) {
Serial.println("Starting CAN failed! ");
delay(250);
}
Serial.println("CAN started");
delay(100);
Does anybody have any ideas on how to troubleshoot this or what the problem is?
There have been a few answers that involve not assuming the SPI bus has been kept the same from the last transaction. I need to reset SPI parameters each time I send a transaction. After going though the libraries I have seen that SPI.begintransaction() is called before every SPI communication, which according to my knowledge, resets the parameters. This implies that I don't need to manually change the SPI bus parameters before each transaction. Am I wrong in this regard?
SPI bus is really simple, and there should be no problem in connecting multiple slaves, as long as, at any time, only one of them has CS_ asserted (low). It can be expected that a library takes control of the CS_ pin, but it also should deassert it after the job is done. If not, then the library would be a very bad one.
You should check hardware and software.
Hardware: use a scope with memory, and look at what happens during initialization. May be that the CS_ pins need a pull-up resistor (the library, if it takes control of its CS_ pin, could choose to put it in high-impedance instead of driving it high). If you don't have a scope you can perhaps monitor the pins by software.
Software: may be the libraries use interrupts? In that case, the program can do things you are unaware of, for example a library can poll a device in background and mess with your code or one from another library. You have to dive deep in the libraries documentation and code. Again, a scope would help a lot.
You didn't specify much about your setup, and your tentative to "manually deselect the CS_ pins) is really worrying. You should check twice that point - if the CS_ pin is high, there is no reason the other SPI device does not work.
Problem was with the level shifter. I connected the OE enable pin to CAN CS, which puts the chip in high impedance when it isn't being used and enables it when I want to send data.
I used my scope to connect to the SPI pins and recorded what was happening. All was working well till I got to MISO. The level shifter was messing with it and pulling it to ground. Basically silencing output from one of the shields.
The learning here is when using level shifters with SPI devices connect the CS to OE.

Cannot connect Wifly to Arduino

I am just an Arduino beginner. I bought an Arduino Uno and a Wifly shield yesterday and I am not able to run the Wifly_Test example program come with WiFlySerial library.
When I look at Serial Monitor, I only saw 2 lines are printed out
1.Starting WiFly Tester.
2.Free memory:XXXX
How can I know that the Wifly Sheild that I bought is not faulty?
I soldered the heard ping to Wifly Shield and stacked it to Aurduino Uno and I can see the LEDs blinking on the Wifly Shield.
Do I need to reset the Wifly Sheild? How do I reset it?
Please point me to the most simple example on how to connect to the router.
I have also bought the shield and had trouble to start with.
If you have soldered the pins to the shield that should be fine but make sure you check they all have a connection and that they don't have solder running down the legs of the pins as this causes the shield to be temperamental.
Run the code below which is from the WiFly library (alpha 2 version) that can be found here:
http://forum.sparkfun.com/viewtopic.php?f=32&t=25216&start=30
Once you see that the shield has connected it will ask for an input, type $$$ and press enter... you have now entered the command line and CMD will be displayed.
If you do not know your network settings type scan and this will display them.
Then set your authentication by typing set wlan auth 3 (Mixed WPA1 & WPA2-PSK) or set wlan auth 4 (WPA2-PSK) this depends on the type of authentication you ise so pick the write one for your network.
Then type set wlan phrase YourPharsePhrase (Change YourPharsePhrase to whatever your WPA key is)
Then type join YourSSIDName (Change YourSSIDName to whatever your network name is)
You see something like this:
join YourSSIDName
Auto-Assoc YourSSIDName chan=1 mode=MIXED SCAN OK
Joining YourSSIDName now..
<2.15> Associated!
DHCP: Start
DHCP in 1234ms, lease=86400s
IF=UP
DHCP=ON
IP=10.0.0.116:2000
NM=255.255.255.0
GW=10.0.0.1
Listen on 2000
you are now connected to your network.
Hopefully this will get you up and running.
N.B. REMEMBER TO CAREFULLY CHECK YOUR PINS! I had great trouble with mine because only a small amount of solder is needed but enough to get a good connection, the balance of this was minute but enough that it wouldn't work. I used a magnifying to check mine in the end.
#include "WiFly.h" // We use this for the preinstantiated SpiSerial object.
void setup() {
Serial.begin(9600);
Serial.println("SPI UART on WiFly Shield terminal tool");
Serial.println("--------------------------------------");
Serial.println();
Serial.println("This is a tool to help you troubleshoot problems with the WiFly shield.");
Serial.println("For consistent results unplug & replug power to your Arduino and WiFly shield.");
Serial.println("(Ensure the serial monitor is not open when you remove power.)");
Serial.println();
Serial.println("Attempting to connect to SPI UART...");
SpiSerial.begin();
Serial.println("Connected to SPI UART.");
Serial.println();
Serial.println(" * Use $$$ (with no line ending) to enter WiFly command mode. (\"CMD\")");
Serial.println(" * Then send each command followed by a carriage return.");
Serial.println();
Serial.println("Waiting for input.");
Serial.println();
}
void loop() {
// Terminal routine
// Always display a response uninterrupted by typing
// but note that this makes the terminal unresponsive
// while a response is being received.
while(SpiSerial.available() > 0) {
Serial.write(SpiSerial.read());
}
if(Serial.available()) { // Outgoing data
//SpiSerial.print(Serial.read(), BYTE);
SpiSerial.write(Serial.read());
}
}
Sorry I forgot to mention , you reset the shield by going to the WiFly library and going to: WiFly/tools/HardwareFactoryReset
Then open the serial monitor and type in any character and this will start the reset.
Thanks everyone who tried to answer me. I finally solved my problem by using Arduino 0023 instead of 1.0.

QextSerialPort connection problem to Arduino

I'm trying to make a serial connection to an Arduino Diecimila board with QextSerialPort. My application hangs though everytime I call port->open(). The reason I think this is happening is because the Arduino board resets itself everytime a serial connection to it is made. There's a way of not making the board reset described here, but I can't figure out how to get QextSerialPort to do that. I can only set the DTR to false after the port has been opened that's not much help since the board has already reset itself by that time.
The code for the connection looks like this:
port = new QextSerialPort("/dev/tty.usbserial-A4001uwj");
port->open(QIODevice::ReadWrite);
port->setBaudRate(BAUD9600);
port->setFlowControl(FLOW_OFF);
port->setParity(PAR_NONE);
port->setDataBits(DATA_8);
port->setStopBits(STOP_1);
port->setDtr(false);
port->setRts(false);
Any ideas on how to get this done. I don't necessarily need to use QextSerialPort should someone know of another library that does the trick.
I'm new to C++ and Qt.
UPDATE:
I noticed that if I run a python script that connects to the same port (using pySerial) before running the above code, everything works just fine.
I had a similar problem.
In my case QExtSerial would open the port, I'd see the RX/TX lights on the board flash, but no data would be received. If I opened the port with another terminal program first QExtSerial would work as expected.
What solved it for me was opening the port, configuring the port settings, and then making DTR and RTS high for a short period of time.
This was on Windows 7 w/ an ATMega32u4 (SFE Pro Micro).
bool serialController::openPort(QString portName) {
QString selectPort = QString("\\\\.\\%1").arg(portName);
this->port = new QextSerialPort(selectPort,QextSerialPort::EventDriven);
if (port->open(QIODevice::ReadWrite | QIODevice::Unbuffered) == true) {
port->setBaudRate(BAUD38400);
port->setFlowControl(FLOW_OFF);
port->setParity(PAR_NONE);
port->setDataBits(DATA_8);
port->setStopBits(STOP_1);
port->setTimeout(500);
port->setDtr(true);
port->setRts(true);
Sleep(100);
port->setDtr(false);
port->setRts(false);
connect(port,SIGNAL(readyRead()), this, SLOT(onReadyRead()));
return true;
} else {
// Device failed to open: port->errorString();
}
return false;
}
libserial is an incredible library I use for stand-alone serial applications for my Arduino Duemilanove.
qserialdevice use!
Example:
http://robocraft.ru/blog/544.html
Can you just use a 3wire serial cable (tx/rx/gnd) with no DTR,RTS lines?

RS-232 confusion under C++

What's the problem in given code? Why it is not showing the output for rs232 when we connect it by the d-9 connector with the short of pin number 2 & 3 in that?
#include <bios.h>
#include <conio.h>
#define COM1 0
#define DATA_READY 0x100
#define SETTINGS ( 0x80 | 0x02 | 0x00 | 0x00)
int main(void)
{
int in, out, status;
bioscom(0, SETTINGS, COM1); /*initialize the port*/
cprintf("Data sent to you: ");
while (1)
{
status = bioscom(3, 0, COM1); /*wait until get a data*/
if (status & DATA_READY)
if ((out = bioscom(2, 0, COM1) & 0x7F) != 0) /*input a data*/
putch(out);
if (kbhit())
{
if ((in = getch()) == 27) /* ASCII of Esc*/
break;
bioscom(1, in, COM1); /*output a data*/
}
}
return 0;
}
Well, the code looks alright. Have you really connected the remaining pins correctly in the plug, see serial and pin connections.
Nothing obvious stands out from your code as the cause. Check all your bases as you are dealing with hardware/software. The following Microsoft article has a different implementation using _bios_serialcom (from bios.h) which might be a good reference point for you.
http://support.microsoft.com/kb/39501
Suggestions for where to go from here:
I would also suggest replacing the literals (eg 0x08) using the constants predefined for Baud rate, Parity (eg _COM_NOPARITY) to make the code more readable in your question.
Check that the Com port is actually open, as its a assumption which is unchecked in your code example above.
Also check up on the pin connections for the DB9. To connect two computers/devices you will need to null modem it, eg pin 2 to pin 3 at the other end, plus the Signal Ground. Make sure you are disabling/not looking for DTR.
If the other computer/device is setup then I would suggest first running HyperTerminal (Programs->Accessories->Communication) and connect to your COM 1 and check you can see characters from the other device. If not its most likely related to your cable.
Hope that helps.
Before checking with your code always check your serial communication with a terminal program. I don't have much experience with Windows environment but in Linux you have programs like cutecom or gtkterm where you can send/receive data from serial port. We extensively used these programs for serial communication in Linux, they are great for debugging potential problems with serial port interface (both h/w & s/w as well). So, before suspecting your code check with a terminal emulator program.
Hey, I am not an expert on Win32, but it seems to be easier to use another article as a source (the one mentioned here before looks outdated):
http://msdn.microsoft.com/en-us/library/ms810467
This is old too, dated around 1995, but it looks still effective. The NT architecture is very restrictive when it comes to grant access to hardware, for example, to send bytes to a PC paralell port one needs to rely on workarounds dll written by open source developers.
I'm assuming from your comment about "pin 2 & 3" that you've connected a loopback cable, so you're expecting to see anything you type come up on the screen (and stop doing so when you disconnect the cable).
I think there's a bug in the code: the if (kbhit()) is inside the if (status & DATA_READY).
That means you only check the keyboard if there is some input ready to receive from the serial port - which there won't be, because you haven't sent it anything yet! Try moving the test and see if it improves matters.
(Here is some similar serial port code that puts the if (kbhit()) test outside the DATA_READY check. It doesn't claim to work, but provides some evidence that this might be the source of the problem...)