Torbjorn in Discussions
上次活动时间: 2024-11-18

Hello I have 3 devices (IOT board using SIM7600 module) sending one value to Thingsspeak. Have been working just fine a couple of years. However 14/11-24 I receive http error code 406 for all 3 devices. The http get is working just fine when testing directly in the browser (https://api.thingspeak.com/update?api_key=xxxxx&field1=33), the server return the entrie number. However, when running the same address via SIM7600 I receive - +HTTPACTION: 0,406,0 Any tips for the 406 error code? Http response error 406 internet says 406 is unaceptable. Perhaps you are making a header request that we dont do. Can you share anything more about the request format? Perhaps there was a security upgrade at our end that your request is not addressing? I believe this is most likely this is because invalid content-type header is being set. The browser automatically sets the header, but, your embedded firmware is setting the header manually and likely using an invalid header. The valid content-type headers are described here: https://www.mathworks.com/help/thingspeak/writedata.html First, I’d like to thank everyone who contributed their suggestions and insights—it’s much appreciated! Since last Thursday, HTTP GET requests from the SIM7600 module to ThingSpeak were returning a 406 error (+HTTPACTION: 0,406,0), indicating that the server found the request unacceptable. However, the same request worked fine in a browser. As suggested that the issue was related to the headers or format of the request being sent by the SIM7600. Actions Taken Debugging the SIM7600 HTTP Request: We used httpbin.org to analyze the actual HTTP headers and payload being sent by the SIM7600 module. It was observed that the User-Agent header was either missing or empty, and no Content-Type header was included. Modifying the HTTP Headers: We added a User-Agent header explicitly using: AT+HTTPPARA="UA","SIM7600_MODULE" This ensures the server recognizes the request as coming from a legitimate source. We added a Content-Type header (though typically required for POST requests, ThingSpeak now seems to enforce it for GET as well): AT+HTTPPARA="CONTENT","application/x-www-form-urlencoded" Validating the Solution: After adding the headers, the HTTP GET request to ThingSpeak worked as expected, and data updates were successful. Testing Workflow: The final working sequence for a GET request to ThingSpeak is as follows: AT+HTTPINIT AT+HTTPPARA="CID",1 AT+HTTPPARA="URL","http://api.thingspeak.com/update?api_key=YOUR_API_KEY&field1=10" AT+HTTPPARA="UA","SIM7600_MODULE" AT+HTTPPARA="CONTENT","application/x-www-form-urlencoded" AT+HTTPACTION=0 The response from AT+HTTPACTION now includes 200 (success), and the channel updates correctly. The issue was resolved by explicitly setting the User-Agent and Content-Type headers in the HTTP request. It seems ThingSpeak has recently implemented stricter validation of HTTP requests, requiring these headers to be present. Thaks so much for the explanation of your journey! Im happy to hear you were able to resolve the problem. Thank you for sharing the steps on your end. Indeed, a recent upgrade of the underlying framework did make the application more strict with respect to certain required headers. sim7600 error 406
Milan Tomin in MATLAB Answers
上次活动时间: 2024-4-8

Having a bizarre problem subscribing to topic with sim7600 hat on raspberry pi. When i try subscribing i get: the following: OK CMQTTSUB: 0,6 CMQTTCONNLOST: 0,1. Code 6 in the CMQTTSUB means failed to receive message. Code 0 in CMQTTCONNLOST means socket closed passively. Why tho? Mqtt actions with sim7600 such as Acquire client, connect, and even publish works without any difficulties in the same project, sub however does not. I'm using thingspeak as a broker, and have tried broker.emqx.io to subscribe to and... it worked without any problem. Has anyone had any similar problem? I've tried subscribing to one or multiple fields, still no dice. Topic strings i've tried: channels/2429193/subscribe/fields/field1 channels/2429193/subscribe/fields/+ channels/2429193/subscribe I provide the code: def setup(self): isSerial2Available = True self.SentMessage('AT+CMQTTDISC=0,60\r\n') time.sleep(0.5) self.SentMessage('AT+CMQTTREL=0\r\n') time.sleep(0.5) self.SentMessage('AT+CMQTTSTART\r\n') # Enable MQTT service. time.sleep(1) connect_cmd = 'AT+CMQTTACCQ=0,"'+ self.ID +'",0,4' # Apply for MQTT client with client ID. self.SentMessage(connect_cmd + '\r\n') time.sleep(1) connect_cmd = 'AT+CMQTTCONNECT=0,"tcp://mqtt3.thingspeak.com",60,1,"'+ self.username +'","'+ self.password +'"' # Send MQTT connection request to the server. self.SentMessage(connect_cmd + '\r\n') time.sleep(2) dataLength = str(len(self.pub)) connect_cmd = "AT+CMQTTTOPIC=0,{}".format(dataLength) # Publish to the inputed topic. self.input_message(connect_cmd, self.pub) time.sleep(1.5) dataLength = str(len('channels/2429193/subscribe')) connect_cmd = "AT+CMQTTSUBTOPIC=0,{},0".format(dataLength) # Subscribe to the inputed topic. self.input_message(connect_cmd, "channels/2429193/subscribe") time.sleep(0.5) self.SentMessage('AT+CMQTTSUB=0\r\n') def SentMessage(self, p_char): global isSerial2Available towrite = p_char.encode() self.ser.write(towrite) time.sleep(1) response = self.ser.read_all().decode() print(response) responses = response.split('\r\n') for resp in responses: if "+CREG: 0," in resp: status = int(resp.split("+CREG: 0,")[1]) # Check if connected to the network. if status == 6: isSerial2Available = False print("\nNetWork Connected") elif "+CMQTTCONNECT: 0," in resp: status = int(resp.split("+CMQTTCONNECT: 0,")[1]) # Check if the client is connected. if status == 0: isSerial2Available = False print("\nMqtt Connected") elif resp == "+CMQTTSTART: 23": isSerial2Available = False print("\nMqtt is already Connected") def input_message(self, p_char, p_data): global startSent self.ser.write(p_char.encode() + b'\r\n') time.sleep(0.2) encodedstr = p_data.encode() + b'\r\n' self.ser.write(p_data.encode() + b'\r\n') time.sleep(1) response = self.ser.read_all().decode() responses = response.split('\r\n') for resp in responses: if "+CMQTTSUB: 0," in resp: status = int(resp.split("+CMQTTSUB: 0,")[1]) if status == 0: print("\nSubTopic Sub") startSent = True self.subThreadStart() def publishData(self, updateMsn): dataLength = str(len(self.pub)) connect_cmd = "AT+CMQTTTOPIC=0,{}".format(dataLength) # Publish to the inputed topic. self.input_message(connect_cmd, self.pub) dataLength = str(len(str(updateMsn))) connect_cmd = "AT+CMQTTPAYLOAD=0,{}".format(dataLength) # Input the publish message self.input_message(connect_cmd, str(updateMsn)) time.sleep(0.5) self.ser.write(b'AT+CMQTTPUB=0,0,120\r\n')
Husnain in MATLAB Answers
上次活动时间: 2023-9-30

Hi, im trying to send data to Thingspeak in bulk/batches. I adopted this example <https://ww2.mathworks.cn/help/thingspeak/continuously-collect-data-and-bulk-update-a-thingspeak-channel-using-an-arduino-mkr1000-board-or-an-esp8266-board.html> . After 1st batch of data is sent to thingspeak successfully, the code doesnot run loop to continue further buffer the data in JSON. That means it send data to server only once and then do nothing. Please guide to sort this issue. #define MODEM_RST 5 #define MODEM_PWKEY 4 #define MODEM_POWER_ON 23 #define MODEM_TX 27 #define MODEM_RX 26 const char apn[] = "***********"; const char gprsUser[] = ""; const char gprsPass[] = ""; const char simPIN[] = ""; const char server[] = "api.thingspeak.com"; const int port = 80; char jsonBuffer[500] = "["; // Initialize the jsonBuffer to hold data #define SerialMon Serial #define SerialAT Serial1 #define TIMEOUT 5000 // Configure TinyGSM library #define TINY_GSM_MODEM_SIM7600 // Modem is SIM7600 #define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb #include <TinyGsmClient.h> #ifdef DUMP_AT_COMMANDS #include <StreamDebugger.h> StreamDebugger debugger(SerialAT, SerialMon); TinyGsm modem(debugger); #else TinyGsm modem(SerialAT); #endif TinyGsmClient client(modem); #define IP5306_ADDR 0x75 #define IP5306_REG_SYS_CTL0 0x00 /* Collect data once every 15 seconds and post data to ThingSpeak channel once every 2 minutes */ unsigned long lastConnectionTime = 0; // Track the last connection time unsigned long lastUpdateTime = 0; // Track the last update time const unsigned long postingInterval = 20L * 1000L; // Post data every 2 minutes const unsigned long updateInterval = 2L * 1000L; // Update once every 15 seconds // Sensor Libraries #include <SPI.h> #include <Adafruit_Sensor.h> #include <DHT.h> #define DHTPIN 32 #define DHTTYPE DHT22 DHT dht(DHTPIN, DHTTYPE); void setup() { SerialMon.begin(115200); // Set modem reset, enable, power pins pinMode(MODEM_PWKEY, OUTPUT); pinMode(MODEM_RST, OUTPUT); pinMode(MODEM_POWER_ON, OUTPUT); digitalWrite(MODEM_PWKEY, LOW); digitalWrite(MODEM_RST, HIGH); digitalWrite(MODEM_POWER_ON, HIGH); // Set GSM module baud rate and UART pins SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX); delay(3000); SerialMon.println("Initializing modem..."); modem.init(); // Configure the wake up source as timer wake up SerialMon.print("Connecting to APN: "); SerialMon.print(apn); if (!modem.gprsConnect(apn, gprsUser, gprsPass)) { SerialMon.println(" fail"); } else { SerialMon.println(" OK"); SerialMon.print("Connecting to "); SerialMon.print(server); if (!client.connect(server, port)) { SerialMon.println(" Fail"); } else { SerialMon.println(" OK"); } } dht.begin(); } void loop() { // If update time has reached 1 second, then update the jsonBuffer if (millis() - lastUpdateTime >= updateInterval) { updatesJson(jsonBuffer); } } // Updates the josnBuffer with data void updatesJson(char* jsonBuffer) { // Collect Hall effect sensor data //int h = hallRead(); float t = dht.readTemperature(); float h = dht.readHumidity(); Serial.print("Temperature: "); Serial.println(t); // Format a single data point as a JSON object char temp[500]; // Temporary buffer for JSON object //sprintf(temp, "{\"delta_t\":%lu,\"field1\":%d},", (millis() - lastUpdateTime) / 1000, t); sprintf(temp, "{\"delta_t\":%lu,\"field1\":%.2f,\"field2\":%.2f},", (millis() - lastUpdateTime) / 1000, t, h); // Append the JSON object to the jsonBuffer strcat(jsonBuffer, temp); // If 15 seconds have passed since the last update, send the data to ThingSpeak if (millis() - lastConnectionTime >= postingInterval) { // Close the JSON array size_t len = strlen(jsonBuffer); jsonBuffer[len - 1] = ']'; // Send data to ThingSpeak httpRequest(jsonBuffer); // Reset the jsonBuffer for the next batch of data jsonBuffer[0] = '['; jsonBuffer[1] = '\0'; } lastUpdateTime = millis(); // Update the last update time } // Updates the ThingSpeakchannel with data void httpRequest(char* jsonBuffer) { // Format the data buffer as noted above char data[500] = "{\"write_api_key\":\"MY_API_KEY\",\"updates\":"; // Replace YOUR-CHANNEL-WRITEAPIKEY with your ThingSpeak channel write API key strcat(data,jsonBuffer); strcat(data,"}"); // Close any connection before sending a new request client.stop(); String data_length = String(strlen(data)+1); //Compute the data buffer length Serial.println(data); // POST data to ThingSpeak if (client.connect(server, 80)) { client.println("POST /channels/MY_CHANNEL_NUMBER/bulk_update.json HTTP/1.1"); // Replace YOUR-CHANNEL-ID with your ThingSpeak channel ID client.println("Host: api.thingspeak.com"); client.println("User-Agent: mw.doc.bulk-update (ESP8266)"); client.println("Connection: close"); client.println("Content-Type: application/json"); client.println("Content-Length: "+data_length); client.println(); client.println(data); String answer=getResponse(); Serial.println( answer ); } else { Serial.println("Failure: Failed to connect to ThingSpeak"); } delay(250); //Wait to receive the response client.parseFloat(); String resp = String(client.parseInt()); Serial.println("Response code:"+resp); // Print the response code. 202 indicates that the server has accepted the response jsonBuffer[0] = '['; //Reinitialize the jsonBuffer for next batch of data jsonBuffer[1] = '\0'; lastConnectionTime = millis(); //Update the last conenction time } String getResponse(){ String response; long startTime = millis(); delay( 200 ); while ( client.available() < 1 && (( millis() - startTime ) < TIMEOUT ) ){ delay( 5 ); } if( client.available() > 0 ){ // Get response from server. char charIn; do { charIn = client.read(); // Read a char from the buffer. response += charIn; // Append the char to the string response. } while ( client.available() > 0 ); } client.stop(); return response; }
Nakajima Makimoto in MATLAB Answers
上次活动时间: 2020-7-23

Hello community, for a few years i have build a monitoring system for ma bees based on the Sodaq Ndogo board with built in SIM800H module. The system works very very good with Thingspeak, but now the 2G network on my region will soon be switched off. I have already bought a Arduino MKR NB 1500 and a Dfrobot SIM7600CE-T 4G(LTE) Shield, but I'm not able to make the boards communicate with Thingspeak. Have anyone of you a Similar project with these boards to share with us? The data from my actual project cam be visualized at www.waabee.ch. Any help would be very appreciated.👍🏻 Greetings from Switzerland

关于 ThingSpeak

The community for students, researchers, and engineers looking to use MATLAB, Simulink, and ThingSpeak for Internet of Things applications. You can find the latest ThingSpeak news, tutorials to jump-start your next IoT project, and a forum to engage in a discussion on your latest cloud-based project. You can see answers to problems other users have solved and share how you solved a problem.