Arduino UNO +sim800l+mqtt(blynk)

sadman41
Offline
Зарегистрирован: 19.10.2016
Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Тяжело для понимая в таком виде..

sadman41
Offline
Зарегистрирован: 19.10.2016

Начиная со стр #9 идёт выплёскивание пакета MQTT: два байта (MQTTProtocolNameLength), которые на картинке "Protocol name (length)", потом четыре байта (MQTTProtocolName) "Protocol name" - "MQTT". Байт (MQTTLVL) "Protocol level"... и т.д.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Получается, это тоже самое что я делала раньше в ручную...

10 2D 00 06 4D 51 49 73 64 70 03 C2 00 3C 00 07 43 49 54 52 4F 45 4E 00 08 64 72 69 76 65 32 72 75 00 0C 6D 61 72 74 69 6E 68 6F 6C 32 32 31

10 маркер авторизации

2D - общая длинна пакета подписки от следующего байта и до конца пакета 2D (HEX) = 42 (DEC) byte

00 - константа

06 - длинна протокола 06 (HEX) = 6 (DEC) byte

4D 51 49 73 64 70 - сам протокол, в ASCII MQIsdp

03 C2 00 3C 00 - постоянная

07 - длинна имени устройства 07 (HEX) = 7 (DEC) byte

43 49 54 52 4F 45 4E - само имя устройства , оно же в ASCII CITROEN

00 - константа

08 - длинна логина 08 (HEX) = 8 (DEC) byte

64 72 69 76 65 32 72 75 - сам логин, в ASCII drive2ru

 

 

Serial.write(0x10); //Печатаю маркер авторизации 

Serial.write(encodedByte);//Это общая длина пакета подписки

do
{encodedByte = X%128;
X = X/128;
if ( X > 0 ) { encodedByte |= 128;
 }
Serial.write(encodedByte);
}
как работает данная конструкция я не понимаю.
Идём далее:
 
Serial.write(MQTTProtocolNameLength >> 8);// Здесь, как Вы сказали, два байта длина Protocol name?
Serial.write(MQTTProtocolNameLength & 0xFF);//?
Serial.write(MQTTProtocolName);//MQIsdp

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Irinka пишет:
как работает данная конструкция я не понимаю.
Не переживайте, я тоже не понял пока её функционал. 

Irinka пишет:

  Serial.write(MQTTProtocolNameLength >> 8);// Здесь, как Вы сказали, два байта длина Protocol name?
  Serial.write(MQTTProtocolNameLength & 0xFF);//? Serial.write(MQTTProtocolName);//MQIsdp

unsigned short MQTTProtocolNameLength; <= два байта.  
Каждый write() выводит по байту - сначала старший, потом младший.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
Serial.write(MQTTProtocolNameLength >> 8);
Serial.write(MQTTProtocolNameLength & 0xFF);
Получается этими двумя строчками я вывожу длину пакета MQTTProtocolName
А затем сам протокол:
Serial.write(MQTTProtocolName);//MQIsdp
 
Надо снова "рисовать" в экселе, оставлю на завтра.
Спасибо. Доброй ночи.
 
vlad072
Offline
Зарегистрирован: 01.08.2017

Вместо тысячи слов

const char* proto  = "MQIsdp";
const byte  ver    =  3;
const char* cid    = "devicename";
const char* willt  = "online";
const char* user   = "username";
const char* pass   = "password";

void brokerconnect () {
  modem.write(0x10);
  modem.write( 4 + 2+strlen(proto) + 2+strlen(cid) + 2+strlen(willt) + 2+1 + 2+strlen(user) + 2+strlen(pass) );
  modem.write((byte)0x00); modem.write(strlen(proto));  modem.write(proto); modem.write(ver);
  modem.write(0xE6); modem.write((byte)0x00); modem.write(0x3C);             // flags, ka timout | E/C -retain/not
  modem.write((byte)0x00); modem.write(strlen(cid));    modem.write(cid);
  modem.write((byte)0x00); modem.write(strlen(willt));  modem.write(willt);  // will topic
  modem.write((byte)0x00); modem.write(0x01);           modem.write('0');    // will message
  modem.write((byte)0x00); modem.write(strlen(user));   modem.write(user);
  modem.write((byte)0x00); modem.write(strlen(pass));   modem.write(pass);
}

 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
modem.write(ver); 

что за константа? версия протокола MQTT?

modem.write(0xE6); modem.write((byte)0x00); modem.write(0x3C);

что за флаг? 00 и 3C это keep alive? а что E6 ? keepAliveInterval?

 

почему после названия устройства печатаются эти строки, а не сразу логин и пароль?

это же только пакет авторизации


  modem.write((byte)0x00); modem.write(strlen(willt));  modem.write(willt);  // will topic
  modem.write((byte)0x00); modem.write(0x01);           modem.write('0');    // will message

 

 

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

http://arduino.ru/forum/programmirovanie/snova-mqtt-1?page=1#comment-460595

тут с комментариями пакет подключения, каждая строчка прокомментирована текстом из официальной документации, там на официальной странице MQTT все описания есть.

http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718028

 

byte sendConnectPacket(byte getSize) {
  byte sizeDevice = strlen(mqtt_device); byte sizeUser = strlen(mqtt_user); byte sizePass = strlen(mqtt_pass);
  byte fullSize = 16 + sizeDevice + sizeUser + sizePass;
  if (getSize) return (fullSize + 2);
  // fixed header
  sendByteToMQTTclient((byte)0x10); // MQTT Control Packet type 0001 connect, reserved 0000
  sendByteToMQTTclient((byte)(fullSize)); // Remaining Length is the length of the variable header (10 bytes) plus the length of the Payload.
  // Variable header
  sendByteToMQTTclient((byte)0x00); // Length MSB (0)
  sendByteToMQTTclient((byte)0x04); // Length LSB (4)
  sendByteToMQTTclient((byte)'M'); sendByteToMQTTclient((byte)'Q'); sendByteToMQTTclient((byte)'T'); sendByteToMQTTclient((byte)'T'); // protocol name
  sendByteToMQTTclient((byte)0x04); // Protocol Level byte
  sendByteToMQTTclient((byte)0xC0); // Connect Flag bits, login and pass enable
  sendByteToMQTTclient((byte)0x00); // Keep Alive MSB (0)
  sendByteToMQTTclient((byte)time_live_connect_packet); // Keep Alive LSB
  // payload
  sendByteToMQTTclient((byte)0x00); // Length MSB (0)
  sendByteToMQTTclient((byte)sizeDevice); // Length LSB (4) - device
  for (byte i = 0; i < sizeDevice; ++i) sendByteToMQTTclient((byte)(mqtt_device[i]));
  sendByteToMQTTclient((byte)0x00); // Length MSB (0)
  sendByteToMQTTclient((byte)sizeUser); // Length LSB (4) - user
  for (byte i = 0; i < sizeUser; ++i) sendByteToMQTTclient((byte)(mqtt_user[i]));
  sendByteToMQTTclient((byte)0x00); // Length MSB (0)
  sendByteToMQTTclient((byte)sizePass); // Length LSB (4) - pass
  for (byte i = 0; i < sizePass; ++i) sendByteToMQTTclient((byte)(mqtt_pass[i]));
}

 

vlad072
Offline
Зарегистрирован: 01.08.2017

1. Да, версия протокола.

2. 0х3С = 60(dec) да, keep alive таймаут. 0xE6 - флаги

MQTT в главе 3 все сообщения доступно разжёваны, рекомендую.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
Will RETAIN (0)
Will QoS (01)
Will flag (1)
Clean Session (1)
прошу пояснить по данным битам, за что отвечают
 
Length MSB (0)
Keep Alive MSB (0)
Что значит MSB, который я называю константой или разделителем
 А так, с пакетом соединения разобралась, поняла что откуда берётся, чуть позже покажу для проверки)
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Integer data values are 16 bits in big-endian order: the high order byte precedes the lower order byte. This means that a 16-bit word is presented on the network as Most Significant Byte (MSB), followed by Least Significant Byte (LSB).

Целочисленные значения данных составляют 16 бит в порядке Биг-эндиана: старший байт предшествует младшему байту. Это означает, что 16-разрядное слово представлено в сети как наиболее значимый байт (MSB), за которым следует наименее значимый байт (LSB).

т е старший и младший байт числа

3.1.2.7 Will Retain
Position: bit 5 of the Connect Flags.
This bit specifies if the Will Message is to be Retained when it is published.
If the Will Flag is set to 0, then the Will Retain Flag MUST be set to 0 [MQTT-3.1.2-15].
If the Will Flag is set to 1:
If Will Retain is set to 0, the Server MUST publish the Will Message as a non-retained message [MQTT-3.1.2-16].
If Will Retain is set to 1, the Server MUST publish the Will Message as a retained message [MQTT-3.1.2-17]..
 
по русски - если нужно чтобы подписанные на топик клиенты видели ранее сохраненное значение то этот флаг должен быть включен
 
Will QoS  - подтверждение получение - есть два варианта, я например только 0 использую, т е без подтверждения, т.к. смысла нет - послал запрос на железку - железка приняла данные - пришел ответ, если ответа нет - проблема. Впрочем дело вкуса.
 
3.1.3.2 Will Topic
If the Will Flag is set to 1, the Will Topic is the next field in the payload
 
я так понимаю что установка флага подразумевает отправку длинного сообщения состоящего из нескольких
 

3.1.2.4 Clean Session

Position: bit 1 of the Connect Flags byte.

This bit specifies the handling of the Session state. 
The Client and Server can store Session state to enable reliable messaging to continue across a sequence of Network Connections. This bit is used to control the lifetime of the Session state

думаю используется для удержания сессии при QoS 1 2, при 0 флаге по окончании таймаута требуется переподключение к серверу или слать ping пакеты через определенные периоды

 

 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Вот что у меня получилось, прошу проверить.

Ссылка на файл эксель https://dropmefiles.com/TpR0W

 

 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

andycat пишет:

Will QoS  - подтверждение получение - есть два варианта, я например только 0 использую, т е без подтверждения, т.к. смысла нет - послал запрос на железку - железка приняла данные - пришел ответ, если ответа нет - проблема. Впрочем дело вкуса.

00 - без подтверждения (4 бит -0 3 бит - 0)

01 - с подтверждением (4 бит - 0 3 бит - 1)

Так?

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016
MaksVV
Offline
Зарегистрирован: 06.08.2015

а зачем переводить всё в байты? я про excel. (или вы учебное пособие делаете?) Вам же дали функцию, она сама всё сделает. 

мой вариант


const char ACCESSPOINT[]= "\"internet.mts.by\"";
const char PROTOCOLIUS[] =  "MQIsdp";               
const char MQTTNAME[]    =  "Ma**V";              
const char MQTTUSER[]    =  "i*****r";            
const char MQTTPASSWORD[] = "1******g";          
const char SERVERNAME_PORT[] = "\"m16.cloudmqtt.com\", \"14325\""; 
#define TIMEBROKER 20   // таймаут бездействия, превысив который с сервера выкинет , мин 


void AUTHsend () 
{
  uint16_t timeBroker = TIMEBROKER;   
  SIM800.write (0x10);
  SIM800.write (strlen(PROTOCOLIUS) + strlen(MQTTNAME) + strlen(MQTTUSER) +  strlen(MQTTPASSWORD) + 12);
  SIM800.write ((byte)0);
  SIM800.write (strlen(PROTOCOLIUS));
  SIM800.write (PROTOCOLIUS);
  SIM800.write (0x03);
  SIM800.write (0xC2);
  timeBroker *=60;
  byte * timeBr = (byte*)&timeBroker;
  SIM800.write(*(timeBr+=1)); // время сеанса связи с брокером, сек (ст. байт)
  SIM800.write(*(--timeBr));  // время сеанса связи с брокером, сек (мл. байт)
  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTNAME));
  SIM800.write (MQTTNAME);
  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTUSER));
  SIM800.write (MQTTUSER);
  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTPASSWORD));
  SIM800.write (MQTTPASSWORD);
  SIM800.write (0x1A);
}

 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

MaksVV пишет:

а зачем переводить всё в байты? я про excel. (или вы учебное пособие делаете?) Вам же дали функцию, она сама всё сделает.

Для интереса.

 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
//Параметры MQTT
const char MQTT_Protocol_Name[] = "MQIsdp";
const char MQTT_Device_Name[] = "SIM800L";
const char MQTT_User_Name[] = "Irinka";
const char MQTT_Password[] = "qwerty";
const byte  MQTT_ver= 3;
const byte  MQTT_Keep_Alive= 60;
const byte  MQTT_MSB=0x00;

const String MQTT_Server = "m23.cloudmqtt.com";
const String MQTT_Port = "10077";

//Параметры MQTT
 
  
void MQTT_CONNECT_Packet(){
  byte Size_MQTT_Protocol_Name=strlen(MQTT_Protocol_Name);
  byte Size_MQTT_Device_Name=strlen(MQTT_Device_Name);
  byte Size_MQTT_User_Name=strlen(MQTT_User_Name);
  byte Size_MQTT_Password=strlen(MQTT_Password);
  byte Size_MQTT_CONNECT_Packet=12+Size_MQTT_Protocol_Name+Size_MQTT_Device_Name+Size_MQTT_User_Name+Size_MQTT_Password;
  DEBUG_PRINTLN(Size_MQTT_CONNECT_Packet);
  
  SIM800.write((byte)0x10);//Fixed header
  SIM800.write((byte)Size_MQTT_CONNECT_Packet);//Remaining Length
  SIM800.write((byte)MQTT_MSB);//Length MSB
  SIM800.write((byte)Size_MQTT_Protocol_Name);//Length LSB
  //Name protokol              
  for (byte i = 0; i<Size_MQTT_Protocol_Name; i++){
    SIM800.write((byte)MQTT_Protocol_Name[i]);
  }
  //Name protokol    
  SIM800.write((byte)MQTT_ver);//Version
  SIM800.write((byte)0xC6);//Connect Flags
  SIM800.write((byte)MQTT_MSB);//Keep Alive MSB
  SIM800.write((byte)MQTT_Keep_Alive);//Keep Alive LSB
  SIM800.write((byte)MQTT_MSB);//Device MSB
  SIM800.write((byte)Size_MQTT_Device_Name);//Device LSB
  //Device_Name            
  for (byte i = 0; i<Size_MQTT_Device_Name; i++){
    SIM800.write((byte)MQTT_Device_Name[i]);
  }
  //Device_Name 
  SIM800.write((byte)MQTT_MSB);//User MSB
  SIM800.write((byte)Size_MQTT_User_Name);//User LSB
  //User_Name            
  for (byte i = 0; i<Size_MQTT_User_Name; i++){
    SIM800.write((byte)MQTT_User_Name[i]);
  }
  //User_Name
  SIM800.write((byte)MQTT_MSB);//Password MSB
  SIM800.write((byte)Size_MQTT_Password);//Password LSB 
  //Password          
  for (byte i = 0; i<Size_MQTT_Password; i++){
    SIM800.write((byte)MQTT_Password[i]);
  }
  //Password
  
}//END void MQTT_CONNECT_Packet(){

 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

MaksVV

а разве не побайтно нужно отправлять текст?

const char PROTOCOLIUS[] = "MQIsdp";

SIM800.write (PROTOCOLIUS);

28   //Name protokol             
29   for (byte i = 0; i<Size_MQTT_Protocol_Name; i++){
30     SIM800.write((byte)MQTT_Protocol_Name[i]);
31   }
32   //Name protokol 

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Irinka пишет:

MaksVV пишет:

а зачем переводить всё в байты? я про excel. (или вы учебное пособие делаете?) Вам же дали функцию, она сама всё сделает.

Для интереса.

 

Лишние телодвижения как я думаю.
Сделайте один раз функцию (или готовую возьмите - выше были) и используйте.
Кстати (любопытно) зачем вам QoS 1?

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

andycat][quote=Irinka пишет:

Кстати (любопытно) зачем вам QoS 1?

Вы про то, что у меня там 1 установлена?

Connect Flags = 0xC6

А так всё верно у меня в коде?

MaksVV
Offline
Зарегистрирован: 06.08.2015

Irinka пишет:
а разве не побайтно нужно отправлять текст?

ну дак напишите минискетч и проверьте свой и мой вариант. Или вот

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Irinka] </p> <p>[quote=andycat пишет:
Irinka пишет:

Кстати (любопытно) зачем вам QoS 1?

Вы про то, что у меня там 1 установлена?

Connect Flags = 0xC6

А так всё верно у меня в коде?

А попробуйте с реальным сервером ;) и там по логам будет видно корректно или нет.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

MaksVV пишет:

Irinka пишет:
а разве не побайтно нужно отправлять текст?

ну дак напишите минискетч и проверьте свой и мой вариант. Или вот

Метод тыка я люблю, это да.

НО...

Опять я путаюсь с write

Я делала как в 59 посту(е).

 

А попробуйте с реальным сервером ;) и там по логам будет видно корректно или нет.

Это конечно же, попробую, но для начала надо разобраться с протоколом отправки? точнее как отправлять

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
byte sendConnectPacket(byte getSize) {

а не 

void sendConnectPacket(byte getSize) {

Я запуталась

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
//Параметры MQTT
const char MQTT_Protocol_Name[] = "MQIsdp";
const char MQTT_Device_Name[] = "SIM800L";
const char MQTT_User_Name[] = "Irinka";
const char MQTT_Password[] = "qwerty";
const byte  MQTT_ver= 3;
const byte  MQTT_Keep_Alive= 60;
const byte  MQTT_MSB=0x00;

const String MQTT_Server = "m23.cloudmqtt.com";
const String MQTT_Port = "10077";

//Параметры MQTT
 
  
void MQTT_Connect_Packet(){
  byte Size_MQTT_Protocol_Name=strlen(MQTT_Protocol_Name);
  byte Size_MQTT_Device_Name=strlen(MQTT_Device_Name);
  byte Size_MQTT_User_Name=strlen(MQTT_User_Name);
  byte Size_MQTT_Password=strlen(MQTT_Password);
  byte Size_MQTT_CONNECT_Packet=12+Size_MQTT_Protocol_Name+Size_MQTT_Device_Name+Size_MQTT_User_Name+Size_MQTT_Password;
  DEBUG_PRINTLN(Size_MQTT_CONNECT_Packet);
  
  SIM800.write(0x10);//Fixed header
  SIM800.write(Size_MQTT_CONNECT_Packet);//Remaining Length
  SIM800.write(MQTT_MSB);//Length MSB
  SIM800.write(Size_MQTT_Protocol_Name);//Length LSB
  SIM800.write(MQTT_Protocol_Name);//Name protokol   
  SIM800.write(MQTT_ver);//Version
  SIM800.write(0xC6);//Connect Flags
  SIM800.write(MQTT_MSB);//Keep Alive MSB
  SIM800.write(MQTT_Keep_Alive);//Keep Alive LSB
  SIM800.write(MQTT_MSB);//Device MSB
  SIM800.write(Size_MQTT_Device_Name);//Device LSB    
  SIM800.write(MQTT_Device_Name);//Device_Name  
  SIM800.write(MQTT_MSB);//User MSB
  SIM800.write(Size_MQTT_User_Name);//User LSB
  SIM800.write(MQTT_User_Name);//User_Name      
  SIM800.write(MQTT_MSB);//Password MSB
  SIM800.write(Size_MQTT_Password);//Password LSB 
  SIM800.write(MQTT_Password); //Password   
  
}//END void MQTT_Connect_Packet(){

Скажите как сделать мой скетч правильно и я пошла соединяться с сервером XDDD (готовить купаты и макароны)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Irinka пишет:

byte sendConnectPacket(byte getSize) {

а не 

void sendConnectPacket(byte getSize) {

Я запуталась

Если getSize = high то функция только возвращает размер пакета, но не отправляет его, т к мне необходимо было знать размер заранее.

ЗЫ. А мне нравиться метод научного тыка - в экспериментах рождается истина.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Irinka пишет:

//Параметры MQTT
const char MQTT_Protocol_Name[] = "MQIsdp";
const char MQTT_Device_Name[] = "SIM800L";
const char MQTT_User_Name[] = "Irinka";
const char MQTT_Password[] = "qwerty";
const byte  MQTT_ver= 3;
const byte  MQTT_Keep_Alive= 60;
const byte  MQTT_MSB=0x00;

const String MQTT_Server = "m23.cloudmqtt.com";
const String MQTT_Port = "10077";

//Параметры MQTT
 
  
void MQTT_Connect_Packet(){
  byte Size_MQTT_Protocol_Name=strlen(MQTT_Protocol_Name);
  byte Size_MQTT_Device_Name=strlen(MQTT_Device_Name);
  byte Size_MQTT_User_Name=strlen(MQTT_User_Name);
  byte Size_MQTT_Password=strlen(MQTT_Password);
  byte Size_MQTT_CONNECT_Packet=12+Size_MQTT_Protocol_Name+Size_MQTT_Device_Name+Size_MQTT_User_Name+Size_MQTT_Password;
  DEBUG_PRINTLN(Size_MQTT_CONNECT_Packet);
  
  SIM800.write(0x10);//Fixed header
  SIM800.write(Size_MQTT_CONNECT_Packet);//Remaining Length
  SIM800.write(MQTT_MSB);//Length MSB
  SIM800.write(Size_MQTT_Protocol_Name);//Length LSB
  SIM800.write(MQTT_Protocol_Name);//Name protokol   
  SIM800.write(MQTT_ver);//Version
  SIM800.write(0xC6);//Connect Flags
  SIM800.write(MQTT_MSB);//Keep Alive MSB
  SIM800.write(MQTT_Keep_Alive);//Keep Alive LSB
  SIM800.write(MQTT_MSB);//Device MSB
  SIM800.write(Size_MQTT_Device_Name);//Device LSB    
  SIM800.write(MQTT_Device_Name);//Device_Name  
  SIM800.write(MQTT_MSB);//User MSB
  SIM800.write(Size_MQTT_User_Name);//User LSB
  SIM800.write(MQTT_User_Name);//User_Name      
  SIM800.write(MQTT_MSB);//Password MSB
  SIM800.write(Size_MQTT_Password);//Password LSB 
  SIM800.write(MQTT_Password); //Password   
  
}//END void MQTT_Connect_Packet(){

Скажите как сделать мой скетч правильно и я пошла соединяться с сервером XDDD (готовить купаты и макароны)

Строки 28 38 41 вы отправляете не строку, а только один байт, в цикле по строке пройдитесь и побайтно отправляйте.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
54   for (byte i = 0; i<Size_MQTT_Password; i++){
55     SIM800.write((byte)MQTT_Password[i]);
56   }

Сделать как и было, спасибо, разберусь с подключением к интернету,отпишусь.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Забыла про байт окончания передачи 

1A - байт окончания передачи пакета

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Irinka пишет:

Забыла про байт окончания передачи 

1A - байт окончания передачи пакета

это где написано?

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
Установка соединения с MQTT брокером
AT+SAPBR=3,1, "Contype","GPRS" - настройка параметров соединения, ответ OK

AT+SAPBR=3,1, "APN","internet.mts.by" - установка точки доступа, ответ OK

AT+SAPBR=1,1 - установка GPRS соединения, ответ OK

AT+SAPBR=2,1 - проверка соединения, ответ +SAPBR: 1,1,"100.78.6.XXX"

AT+CIPSTART="TCP","m23.cloudmqtt.com","10077" - установка связи с сервером, ответ CONNECT OK

AT+CIPSEND - команда на отпраку пакета

пакет авторизации MQTT_CON()

пакет публикации MQTT_PUB()

пакет подписки MQTT_SUB()

1A - байт окончания передачи пакета

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Irinka пишет:

Установка соединения с MQTT брокером
AT+SAPBR=3,1, "Contype","GPRS" - настройка параметров соединения, ответ OK

AT+SAPBR=3,1, "APN","internet.mts.by" - установка точки доступа, ответ OK

AT+SAPBR=1,1 - установка GPRS соединения, ответ OK

AT+SAPBR=2,1 - проверка соединения, ответ +SAPBR: 1,1,"100.78.6.XXX"

AT+CIPSTART="TCP","m23.cloudmqtt.com","10077" - установка связи с сервером, ответ CONNECT OK

AT+CIPSEND - команда на отпраку пакета

пакет авторизации MQTT_CON()

пакет публикации MQTT_PUB()

пакет подписки MQTT_SUB()

1A - байт окончания передачи пакета

 

а....ну да, я немного по другому шлю

http://arduino.ru/forum/programmirovanie/snova-mqtt-1#comment-411540

 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Для повышения образованности и дальнейших "экспериментов"

const byte MQTT_Connect_Flags=B11000110;
//7 bit User name flag (1)
//6 bit Password flag (1)
//5 bit Will RETAIN (0)
//4 bit Will QoS (0)
//3 bit Will QoS (0)
//2 bit Will flag (1)
//1 bit Clean Session (1)
//0 bit не используется
  SIM800.write(MQTT_Connect_Flags);//Connect Flags

Вот так можно будет отправлять байт флага, вместо   SIM800.write(0xC6);//Connect Flags

И уж сразу  еще вопрос, я же могу хранить эти переменные во флеш памяти?

const char MQTT_Password[] PROGMEM= "qwerty";
const byte MQTT_Connect_Flags PROGMEM =B11000110;
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Можно все, вопрос зачем, памяти не хватает или что? 10 байт вас не спасут,а лишнее написание кода добавится.

MaksVV
Offline
Зарегистрирован: 06.08.2015
andycat пишет:
Строки 28 38 41 вы отправляете не строку, а только один байт, в цикле по строке пройдитесь и побайтно отправляйте.
 
Разве?
 
Irinka пишет:
Метод тыка я люблю, это да.
 
andycat пишет:
А мне нравиться метод научного тыка - в экспериментах рождается истина.
 
Нет, главное оба любят эксперименты, но никто их не делает. А как же: 
 
MaksVV пишет:
ну дак напишите минискетч и проверьте свой и мой вариант. Или вот
 

const char MQTT_Protocol_Name[] = "MQIsdp";

void setup() 
{
  Serial.begin (19200);
  Serial.write(MQTT_Protocol_Name);
}

void loop() {}

 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Irinka пишет:

MaksVV пишет:

а зачем переводить всё в байты? я про excel. (или вы учебное пособие делаете?) Вам же дали функцию, она сама всё сделает.

Для интереса.

..."какая у людей интересная жизнь"... Полад Бюльбуль-Оглы

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

MaksVV пишет:

andycat пишет:
Строки 28 38 41 вы отправляете не строку, а только один байт, в цикле по строке пройдитесь и побайтно отправляйте.
 
Разве?
 
Irinka пишет:
Метод тыка я люблю, это да.
 
andycat пишет:
А мне нравиться метод научного тыка - в экспериментах рождается истина.
 
Нет, главное оба любят эксперименты, но никто их не делает. А как же: 
 
MaksVV пишет:
ну дак напишите минискетч и проверьте свой и мой вариант. Или вот
 

const char MQTT_Protocol_Name[] = "MQIsdp";

void setup() 
{
  Serial.begin (19200);
  Serial.write(MQTT_Protocol_Name);
}

void loop() {}

 

 

в С слаб, может и не прав, спасибо, попробую.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Я в С ещё слабее вашего, однако действовал методом научного тыка. Действительно помогает! Так сказать стараюсь сразу проверять на практике. 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
2019-12-05 18:05:57: New connection from 156.69.19.234 on port 11481.
2019-12-05 18:06:03: Socket error on client <unknown>, disconnecting.

Вот что ответил сервер

MaksVV
Offline
Зарегистрирован: 06.08.2015

полный скетч покажите

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Тестовый скетч

#include <SoftwareSerial.h>
SoftwareSerial SIM800(6,7);

//Пины Nano
#define P0  (1 << 0)
#define P1  (1 << 1)
#define P2  (1 << 2)
#define P3  (1 << 3)
#define P4  (1 << 4)
#define P5  (1 << 5)
#define P6  (1 << 6)
#define P7  (1 << 7)

#define RESETSIM_OUTPUT    (DDRB  |=  P0)
#define RESETSIM_HIGH      (PORTB |=  P0)
#define RESETSIM_LOW       (PORTB &= ~P0)

//Отладка
#define DEBUG
#ifdef DEBUG
#define SERIAL_BEGIN         Serial.begin(19200)
#define DEBUG_PRINT(x)       Serial.print (x)
#define DEBUG_PRINTLN(x)     Serial.println (x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#define SERIAL_BEGIN
#endif
//Отладка


//Параметры MQTT
const char MQTT_Protocol_Name[] = "MQIsdp";
const char MQTT_Device_Name[] = "SIM800L";
const char MQTT_User_Name[] = "123456";
const char MQTT_Password[] = "1223456";
const byte  MQTT_ver= 3;
const byte  MQTT_Keep_Alive= 60;
const byte  MQTT_MSB=0x00;
const String MQTT_Server = "m10.cloudmqtt.com";
const String MQTT_Port = "10077";
const byte MQTT_Connect_Flags=B11000110;
//7 bit User name flag (1)
//6 bit Password flag (1)
//5 bit Will RETAIN (0)
//4 bit Will QoS (0)
//3 bit Will QoS (0)
//2 bit Will flag (1)
//1 bit Clean Session (1)
//0 bit не используется

//Параметры MQTT


//Нужные АТ команды
const String AT_komandu[]  ={
"AT",//Проверка связи                          0
"ATE1",
"AT+CCALR?",//Проверка сети                     1
"AT+CLIP=1",//"Ustanovlen AON                  2
"AT+CMGF=1",//"Text mode                       3
"AT+CMGDA=\"DEL ALL\"",//Sms udaleny             4
"ATH",//Sbros vhodiashchego                       5
"AT+SAPBR=3,1, \"Contype\",\"GPRS\"",//             6
"AT+SAPBR=3,1, \"APN\",\"internet.tele2.ru\"",//    7
"AT+SAPBR=3,1,\"USER\",\"\"",//                     8
"AT+SAPBR=3,1,\"PWD\",\"\"",//                      9
"AT+SAPBR=1,1",//установка GPRS связи             10
"AT+CSTT=\"www\",\"\",\"\"",//11
"AT+CIICR",//12
"AT+CIFSR",//13
"AT+CIPSTART=\"TCP\",\"m10.cloudmqtt.com\",\"11481\"",//14
"AT+CIPSEND",//15
"AT+SAPBR=2,1",//полученный IP адрес             11
"AT+SAPBR=4,1", //текущие настройки соединения     12
"AT+SAPBR=0,1", //разорвать GPRS соединени        13
};



unsigned long TimePoiska;


//AT+SAPBR=3,1, "Contype","GPRS"
//AT+SAPBR=3,1, "APN","internet.tele2.ru"


//GPRS AT command

int i = 0;


//Пакет соединения  
void MQTT_CONNECT_Packet(){
  byte Size_MQTT_Protocol_Name=strlen(MQTT_Protocol_Name);
  byte Size_MQTT_Device_Name=strlen(MQTT_Device_Name);
  byte Size_MQTT_User_Name=strlen(MQTT_User_Name);
  byte Size_MQTT_Password=strlen(MQTT_Password);
  byte Size_MQTT_CONNECT_Packet=12+Size_MQTT_Protocol_Name+Size_MQTT_Device_Name+Size_MQTT_User_Name+Size_MQTT_Password;
  SIM800.write(0x10);//Fixed header
  SIM800.write(Size_MQTT_CONNECT_Packet);//Remaining Length
  SIM800.write(MQTT_MSB);//Length MSB
  SIM800.write(Size_MQTT_Protocol_Name);//Length LSB  
  for (byte i = 0; i<Size_MQTT_Protocol_Name; i++){SIM800.write(MQTT_Protocol_Name[i]);}//Name protokol  
  SIM800.write(MQTT_ver);//Version
  SIM800.write(0xC6);//Connect Flags
  SIM800.write(MQTT_MSB);//Keep Alive MSB
  SIM800.write(MQTT_Keep_Alive);//Keep Alive LSB
  SIM800.write(MQTT_MSB);//Device MSB
  SIM800.write(Size_MQTT_Device_Name);//Device LSB          
  for (byte i = 0; i<Size_MQTT_Device_Name; i++){SIM800.write(MQTT_Device_Name[i]);}//Device_Name 
  SIM800.write(MQTT_MSB);//User MSB
  SIM800.write(Size_MQTT_User_Name);//User LSB
  for (byte i = 0; i<Size_MQTT_User_Name; i++){SIM800.write(MQTT_User_Name[i]);}//User_Name
  SIM800.write(MQTT_MSB);//Password MSB
  SIM800.write(Size_MQTT_Password);//Password LSB          
  for (byte i = 0; i<Size_MQTT_Password; i++){SIM800.write(MQTT_Password[i]);}//Password   
  SIM800.write(0x1A);//End flag
}//END void MQTT_CONNECT_Packet()






void setup(){
  SERIAL_BEGIN;
  SIM800.begin(38400);
  RESETSIM_OUTPUT;
  RESETSIM_LOW;
  delay(1000);
  RESETSIM_HIGH;
  delay(1000);
  DEBUG_PRINTLN("Onload MQTT");
  delay(5000);
  TimePoiska=millis();
}

void loop(){

if (SIM800.available()){
  Serial.write(SIM800.read()); 
}

/*if (Serial.available()) {
SIM800.write(Serial.read());
}*/


if (millis()-TimePoiska>=2000){
TimePoiska=millis();  
i++;
if (i>16){
i=0;
MQTT_CONNECT_Packet();

}
DEBUG_PRINTLN("Komanda: "+AT_komandu[i]);
SIM800.println(AT_komandu[i]);

}








}

 

vlad072
Offline
Зарегистрирован: 01.08.2017

Мне кажется Вам реально заняться нечем в плохом смысле. Вам скинули несколько готовых функций, пользуйтесь, не нужно ничего придумывать. Так же ссылку на самый подробный солюшн по MQTT, даже с примерами, изучайте. Всё равно не понятно? - Сопоставьте первое со вторым.

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

Стоп, всё сконнектилось, ошибка была из-за повторной отправки 

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

А чуть позже на сервере

2019-12-05 18:16:58: Log cleared by user
2019-12-05 18:17:08: New connection from 176.59.100.9 on port 11481.
2019-12-05 18:18:38: Client <unknown> has exceeded timeout, disconnecting.
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Irinka пишет:

А чуть позже на сервере

2019-12-05 18:16:58: Log cleared by user
2019-12-05 18:17:08: New connection from 176.59.100.9 on port 11481.
2019-12-05 18:18:38: Client <unknown> has exceeded timeout, disconnecting.

и чудненько!!!

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017

ua6em пишет:

Irinka пишет:

А чуть позже на сервере

2019-12-05 18:16:58: Log cleared by user
2019-12-05 18:17:08: New connection from 176.59.100.9 on port 11481.
2019-12-05 18:18:38: Client <unknown> has exceeded timeout, disconnecting.

и чудненько!!!

В каком смысле?

Irinka
Irinka аватар
Offline
Зарегистрирован: 28.06.2017
MQTT
1 connections

176.59.110.172:4546
MQTT over SSL
No connections

Websockets
No connections

Сервер пишет что подключение есть. 

буду отправлять данные

MaksVV
Offline
Зарегистрирован: 06.08.2015

на примерно таком же скетче я тоже познавал MQTT. Но сразу скажу, что нужно работать  с модемом в режиме диалога. Т.е. если с сервера выкидывает происходило переподключение и т.д. А этот скетч чисто для проверки подключения к брокеру. 

#include <SoftwareSerial.h>
      SoftwareSerial SIM800 (6, 7);//Rx, Tx   //UART для соединения с GSM модулем

//---------------------------Настройки MQTT-----------------------------------------------------------------------------

const char ACCESSPOINT[]= "\"internet.mts.by\"";     // точка доступа оператора связи симкарты
const char PROTOCOLIUS[] =  "MQIsdp";                // это и оставляем
const char MQTTNAME[]    =  "Ma   V";                // это смотрим на сервере MQTT
const char MQTTUSER[]    =  "i       r";              // это смотрим на сервере MQTT
const char MQTTPASSWORD[] = "1        g";          // это смотрим на сервере MQTT
const char SERVERNAME_PORT[] = "\"m16.cloudmqtt.com\", \"14325\""; // это смотрим на сервере MQTT
#define TIMEBROKER 20   // таймаут бездействия с брокером, мин (при превышении его с сервера выкидывает)

//----------------------------------------------------------------------------------------------------------------------

byte Init = 1;   // переменная автомат инита 
int temper = 25; // так просто переменная, например температуры 

void setup() 
{
delay (5000);           // ждём пока модем одуплится
Serial.begin(19200);    // отладка
SIM800.begin(38400);    // сериал соединение для gsm модуля
}

void loop() 
{

SIM800setting ();       // настройка модема   
if (SIM800.available()>0) Serial.write(SIM800.read());  // отладка модема
sendDataMQTT();         // периодическая отправка данных на брокер



}


void SIM800setting ()
{
 
 static uint32_t previnit  = 0;

if (Init<=11 && millis() - previnit>3000)
{  
      
      if (Init == 1) SIM800.println (F("AT+CIPHEAD=1"));
 else if (Init == 2) SIM800.println (F("AT+CMGF=1"));
 else if (Init == 3) SIM800.println (F("AT+IFC=0, 0"));
 else if (Init == 4) SIM800.println (F("AT+GSMBUSY=1"));
 else if (Init == 5) SIM800.println (F("AT+CNMI=1,2,2,1,0"));
 else if (Init == 6) SIM800.println (F("AT+SAPBR=3,1, \"Contype\",\"GPRS\""));
 else if (Init == 7) SIM800.print (F("AT+SAPBR=3,1, \"APN\",")), SIM800.println (ACCESSPOINT);
 else if (Init == 8) SIM800.println (F("AT+SAPBR=1,1"));
 else if (Init == 9) SIM800.print (F("AT+CIPSTART=\"TCP\",")),  SIM800.println (SERVERNAME_PORT);
 else if (Init == 10)  AUTHsend ();            // отправка брокеру пакета авторизации 
 else if (Init == 11)  SUBsend("top/#");       // подписка на топики
previnit = millis();
Init++;
}

}



 void AUTHsend () 
{
  SIM800.println (F("AT+CIPSEND"));
  delay (250);
  uint16_t timeBroker       = TIMEBROKER;   
  SIM800.write (0x10);
  SIM800.write (strlen(PROTOCOLIUS) + strlen(MQTTNAME) + strlen(MQTTUSER) +  strlen(MQTTPASSWORD) + 12);
  SIM800.write ((byte)0);
  SIM800.write (strlen(PROTOCOLIUS));
  SIM800.write (PROTOCOLIUS);
  SIM800.write (0x03);
  SIM800.write (0xC2);
  timeBroker *=60;
  byte * timeBr = (byte*)&timeBroker;
  SIM800.write(*(timeBr+=1)); // время сеанса связи с брокером, сек (ст. байт)
  SIM800.write(*(--timeBr));  // время сеанса связи с брокером, сек (мл. байт)
  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTNAME));
  SIM800.write (MQTTNAME);
  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTUSER));
  SIM800.write (MQTTUSER);
  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTPASSWORD));
  SIM800.write (MQTTPASSWORD);
  SIM800.write (0x1A);
}


void SUBsend (char topSub[20]) {
  SIM800.println (F("AT+CIPSEND"));
  delay (250);
  SIM800.write (0x82);
  SIM800.write (strlen(topSub) + 5);
  SIM800.write ((byte)0);
  SIM800.write (0x01);
  SIM800.write ((byte)0);
  SIM800.write (strlen(topSub));
  SIM800.write (topSub);
  SIM800.write ((byte)0x00);
  SIM800.write (0x1A);
}

void PUBsend  (char topPub[30], String Command) 
{
  SIM800.println (F("AT+CIPSEND"));
  delay (250);
  SIM800.write (0x30);
  SIM800.write (strlen (topPub) + Command.length() + 2);
  SIM800.write ((byte)0x00);
  SIM800.write (strlen (topPub));
  SIM800.write (topPub);
  for (byte i = 0; i < Command.length(); i++) SIM800.write (Command[i]);
  SIM800.write(0x1A); 
}


void sendDataMQTT()
{
  if (Init>=12) // если инит модема завершен
    {  
      static uint32_t prev = 0; 
      if (millis() - prev>5000)    //периодически отправляем топик с температурой на брокер
        {
          PUBsend ("top/temp", String(temper));
          prev = millis(); 
        }
     }
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Irinka пишет:

ua6em пишет:

Irinka пишет:

А чуть позже на сервере

2019-12-05 18:16:58: Log cleared by user
2019-12-05 18:17:08: New connection from 176.59.100.9 on port 11481.
2019-12-05 18:18:38: Client <unknown> has exceeded timeout, disconnecting.

и чудненько!!!

В каком смысле?

В прямом, сервер подождал 30 секунд данные и отключился.
Я ж выше давал ссылку на описание и пример команд и там чёрным по русски было написано что в пакете connect указывать время соединения, будьте добры или данные отправлять каждые 20 секунд или переподключаться.