sur un sim800L j’essaye de récupéré le niveau de signal.
Comme ça sur le Serial je recupere des valeurs de 14 à 17 en déplacent le module (“logique”)
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
SoftwareSerial mySerial(32, 33);
void setup()
{
Serial.begin(9600);
mySerial.begin(9600);
delay(1000);
lcd.init();
lcd.backlight() ;
}
void loop()
{
mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
updateSerial();
delay(2000);
}
void updateSerial()
{
while(mySerial.available())
{
Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
}
}
Par contre avec cette ligne en + pour afficher la valeur sur le LCD elle reste affiché à 10:
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
SoftwareSerial mySerial(32, 33);
void setup()
{
Serial.begin(9600);
mySerial.begin(9600);
delay(1000);
lcd.init();
lcd.backlight() ;
}
void loop()
{
mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
updateSerial();
delay(2000);
}
void updateSerial()
{
while(mySerial.available())
{
lcd.setCursor(0,0); // lcd.setCursor(ligne,colonne)
lcd.print(mySerial.read());
}
}
void updateSerial()
{
while(mySerial.available())
{
//Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
char c=mySerial.read();
if(c==':'){
char c=mySerial.read();
}
mais j'ai que le : qui est affiché sur le serial.
J'ai rajouter un while :
void updateSerial()
{
while(mySerial.available())
{
//Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
char c=mySerial.read();
if(c==':'){
while(mySerial.available())
{
char d=mySerial.read();
Serial.print (d) ;
}}
Tu peux mettre les caractères reçus dans un String au fur et à mesure de leur arrivée et utiliser les fonctions de recherche et de transformation de la classe String pour extraire ce que tu veux.
Ça doit aussi pouvoir se faire avec un tableau de char à la place du String.
Mais à utiliser avec modération, car elle a tendance a fragmenter la mémoire. Donc pour une utilisation au début ou de temps en temps dans la loop, ça va. Si ton programme crée des String ou les change (taille notamment) régulièrement pendant l'exécution, tu risques d'avoir des erreurs ou des crashes dus à la mémoire.
Oui, c’est une solution.
Si tu veux éliminer la RTC, tu devrais rester sur l’utilisation de tableaux de char et abandonner le String. Je te l’ai proposé car c’est une solution de facilité, mais elle a des inconvénients.
Pour les fonctions sur les tableaux de char, voir ici
Je vais garder le RTC et régler son heure dans le setup() . comme ça pas de dérive ou de reprogrammation en cas de pile défectueuse. moins de risque de plantage du programme.
Le code fonctionne bien, mais si j'envoie une 2ème commande dans le buffer pour indiquer une date différente, elle n'est pas prise en compte, je pensais vider le stringOne avec un stringOne = ""; mais sans succès
unsigned long previousMillis = 0;
const long interval = 5000;
char bufferReception;
int etatBuffer;
String stringOne = "";
byte n;
String jourString, moisString, anneeString, heureString, minutesString, secondeString;
int jour, mois, annee, heure, minutes, seconde;
void setup()
{
Serial.begin(9600);
}
void loop()
{
unsigned long currentMillis = millis();
etatBuffer = Serial.available();
while (etatBuffer > 0)
{ bufferReception = Serial.read();
stringOne = stringOne + bufferReception;
etatBuffer = Serial.available();
}
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
n = stringOne.indexOf("/", 0);
anneeString = stringOne.substring(n - 2, n);
moisString = stringOne.substring(n + 1, n + 3);
jourString = stringOne.substring(n + 4, n + 6);
heureString = stringOne.substring(n + 7, n + 9);
minutesString = stringOne.substring(n + 10, n + 12);
secondeString = stringOne.substring(n + 13, n + 15);
jour = jourString.toInt();
mois = moisString.toInt();
annee = anneeString.toInt();
heure = heureString.toInt();
minutes = minutesString.toInt();
seconde = secondeString.toInt();
Serial.print(jour); Serial.print("/");
Serial.print(mois); Serial.print("/");
Serial.print(annee);
Serial.print(" ");
Serial.print(heure); Serial.print(":");
Serial.print(minutes); Serial.print(":");
Serial.println(seconde);
}
}
comme la communication est “série”, le plus simple reste quand même d’utiliser les techniques de gestion du port Série → petit tuto sur le sujet
j’avais fait ce code il y a un certain temps en exemple qui utilise sscanf() pour extraire des infos. ça tournait sur un MEGA avec le SIM800 connecté sur le Serial3 (défini par #define gsm Serial3).
Sur un UNO faudrait définir gsm comme un port Sowftare Serial.
#define gsm Serial3
const char * ATString = "AT";
const char * OKString = "\r\nOK\r\n";
const uint32_t oneSecond = 1000ul;
const byte maxMessageSize = 200;
char GSM_MessageLine[maxMessageSize + 1]; // +1 as we want to be able to store the trailing '\0'
// --------------------------------------
// gsmPrintlnATCommand executes an AT commmand by adding at the end a CR LF
// then it checks if endMarker string is receivedon the GSM Serial port
// for max duration ms returns a boolean stating if the marker was found
// with the verbose option, the output from the GSM is also printed to Serial
// --------------------------------------
boolean gsmPrintlnATCommand(const char * command, const char * endMarker, unsigned long duration, boolean verbose)
{
gsm.println(command);
return waitForString(endMarker, duration, verbose);
}
// --------------------------------------
// gsmPrintATCommand or gsmpWriteATCommand is used when you don't want to send the CR LF
// at the end of the commmand line; use it to build up a multi part command
// same syntax as print as they are Variadic Macros using print or write
// --------------------------------------
#define gsmPrintATCommand(...) gsm.print(__VA_ARGS__)
#define gsmWriteATCommand(...) gsm.write(__VA_ARGS__)
// --------------------------------------
// read a line from gsm, ignore '\r' and returns true if '\n' is found
// --------------------------------------
boolean getGSMLine()
{
static byte indexMessage = 0;
boolean incomingMessage = true;
while (gsm.available() && incomingMessage) {
int c = gsm.read();
if (c != -1) {
// Serial.write((uint8_t) c); // si vous voulez voir ce qui arrive
switch (c) {
case '\n':
GSM_MessageLine[indexMessage] = '\0'; // trailing NULL char for a correct c-string
indexMessage = 0; // get ready for next time
incomingMessage = false;
break;
case '\r': // don't care about this one
break;
default:
if (indexMessage <= maxMessageSize - 1) GSM_MessageLine[indexMessage++] = (char) c; // else ignore it..
break;
}
}
}
return !incomingMessage;
}
// --------------------------------------
// waitForString wait max for duration ms whilst checking if endMarker string is received
// on the GSM Serial port returns a boolean stating if the marker was found
// --------------------------------------
boolean waitForString(const char * endMarker, unsigned long duration, boolean verbose)
{
int localBufferSize = strlen(endMarker);
char localBuffer[localBufferSize];
int index = 0;
boolean endMarkerFound = false;
unsigned long currentTime;
memset(localBuffer, '\0', localBufferSize); // clear buffer
currentTime = millis();
while (millis() - currentTime <= duration) {
if (gsm.available() > 0) {
if (index == localBufferSize) index = 0;
localBuffer[index] = (uint8_t) gsm.read();
if (verbose) Serial.print((char) localBuffer[index]);
endMarkerFound = true;
for (int i = 0; i < localBufferSize; i++) {
if (localBuffer[(index + 1 + i) % localBufferSize] != endMarker[i]) {
endMarkerFound = false;
break;
}
}
index++;
}
if (endMarkerFound) break;
}
return endMarkerFound;
}
void setup()
{
Serial.begin(115200);
gsm.begin(57600); // test 1200 , 2400, 4800, 9600, 19200, 38400, 57600, 115200.
// for SIM800L and autobauding Serial and gsm should have the same baud rate and max is 57600
// prévoir éventuellement AT+CPIN=xxxx pour rentrer le PIN
// we wait until the module answers to AT command with an OK
bool waitForBoot = true;
while (waitForBoot) {
if (gsmPrintlnATCommand(ATString, OKString, oneSecond, false)) {
Serial.println(F("GPRS Modem OK"));
waitForBoot = false;
} else {
Serial.write('.');
delay(oneSecond);
}
}
Serial.println("Initialisation OK");
}
void loop()
{
// on lit une commande AT que l'utilisateur tape sur la console série et on l'envoie au gsm
while (Serial.available()) {
int r = Serial.read();
if (r != -1) {
gsm.write((uint8_t) r);
}
}
if (getGSMLine()) {
// ici on peut tester si la réponse est quelque chose d'intéressant
// ********************************************
// par exemple analyse de la réponse à AT+CSQ
if (!strncmp(GSM_MessageLine, "+CSQ:", 5)) { // 5 parce que "+CSQ:" c'est 5 caractères, on compare le début de la chaîne
int rssi, ber;
if ( sscanf(GSM_MessageLine, "+CSQ: %d,%d", &rssi, &ber) == 2) {
Serial.print(F("Qualité de reception = ")); Serial.println(rssi);
Serial.print(F("Code Erreur = ")); Serial.println(ber);
}
}
// ********************************************
// Autres test...
else if (!strncmp(GSM_MessageLine, "+TOTO:", 6)) {
} else {
Serial.println(GSM_MessageLine); // sinon on imprime simplement la réponse
}
}
}