Pressure Map Data Transfer Issues

So the premise is I'm collecting data from a 16x16 pressure map using a Mega 2560. The data from the map is being stored in an SD card on an Adafruit WINC1500 Wifi shield. The problem occurs after it's re-read for sending to Adafruit IO.

Ideally I'd be sending the 256 values from each reading through char array with delimiters (as values from the sensor range between 0 and 1000 they have no set length therefore require a delimiter).

When I attempt to publish to Adafruit the maximum size char array that will send is 100 characters/bytes.

Would a char array of 512-1000 characters just be too large to send? Does anyone have an idea of which component would be struggling with this?

baynesstua: Does anyone have an idea of which component would be struggling with this?

Who knows with no code.

Please read and follow the directions in the “How to use this forum” post.

Sorry. For anyone who’s able to help I’ll attach the code to this.

   #include <SD.h>
   #include <SPI.h>
   #include <WiFi101.h>
   #include <Wire.h>
   #include <Adafruit_PN532.h>
   #include <Adafruit_MQTT.h>
   #include <Adafruit_MQTT_Client.h>
   #include <Adafruit_MPR121.h>
   #include <Chrono.h>
   #include <LightChrono.h>
   
   //WLAN
   char ssid[] = "AndroidAP";
   char pass[] = "xvpw4672";
   int keyIndex = 0;
   int status = WL_IDLE_STATUS;
   
   //ADAFRUIT
   #define AIO_SERVER      "io.adafruit.com"
   #define AIO_SERVERPORT  1883
   #define AIO_USERNAME    -
   #define AIO_KEY         -
   WiFiClient client;
   Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
   #define halt(s) { Serial.println(F( s )); while(1);  }
   
   //PN532
   #define PN532_SCK  (2)
   #define PN532_MOSI (3)
   #define PN532_SS   (4)
   #define PN532_MISO (5)
   #define PN532_IRQ  (2)
   #define PN532_RESET (3)
   uint8_t success;
   uint32_t cardid = 0;
   uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; 
   uint8_t uidLength;    
   Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
   
   //MPR121
   Adafruit_MPR121 cap = Adafruit_MPR121();
   uint16_t lasttouched = 0;
   uint16_t currtouched = 0;
   unsigned long time;
   String left;
   String right;
   
   //P.MAP
   const int Cols = 16;
   const int Rows = 16;
   const int Level = 1.2;
   int Pin[]= {A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, A5, A4, A3, A2, A1, A0}; 
   int dPin[] = {23, 22, 25, 24, 27, 26, 29, 28, 31, 30, 33, 32, 35, 34, 37, 36};
   int i = 0;
   int j = 0;
   int k = 0;
   int n = 0;
   int m = 0;
   int sensorValue[Cols];
   int msensorValue[Cols];
   const unsigned char PS_16 = (1 << ADPS2);
   const unsigned char PS_32 = (1 << ADPS2) | (1 << ADPS0);
   const unsigned char PS_64 = (1 << ADPS2) | (1 << ADPS1);
   const unsigned char PS_128 = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
   int count = 0;
   File pmap;
   
   //OTHER FIELDS
   Chrono chrono;
   int finalise = 0;
   #define LEDPIN 13
   void(* resetFunc) (void) = 0;
   
   void setup() {
     
     while (!Serial);
     Serial.begin(38400);
   
   //SD CARD
     if (!SD.begin(4)) {
       Serial.println("SD not found");
       while (1);
     }
     SD.remove("pmap.txt");
   
   //WINC1500
     if (WiFi.status() == WL_NO_SHIELD) {
       Serial.println("WINC1500 not found");
       resetFunc();
     }
     Serial.println("WINC1500 found");
     pinMode(LEDPIN, OUTPUT);
   
   //MPR121
     if (!cap.begin(0x5A)){
       Serial.println ("MPR121 not found");
       while (1);
     }
     Serial.println("MPR121 found");
   
   //P.MAP
     for (int k = Rows-1; k >= 0 ; k--) {
         pinMode(dPin[k], OUTPUT);
         }
     for (j = 0; j >= Rows-1 ; j++) {
         pinMode (Pin[i], INPUT);
         }
     ADCSRA &= ~PS_128;
     ADCSRA |= PS_32;
     
   //NFC
     nfc.begin();
     uint32_t versiondata = nfc.getFirmwareVersion();
     if (!versiondata){
       Serial.print("PN352 not found");
       while (1); //halt
     }
   
     Serial.println("PN532 found"); Serial.println((versiondata>>24) & 0xFF, HEX);
     Serial.println("Firmware ver. "); Serial.println((versiondata>>16) & 0xFF, DEC);
     nfc.SAMConfig();
     Serial.println("Waiting for an ISO14443A Card...");
     success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
     if (success) {
       nfc.PrintHexChar(uid, uidLength);
       if (uidLength == 4)
       {
         uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
         success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);
   
            cardid = uid[0];
            cardid <<= 8;
            cardid |= uid[1];
            cardid <<= 8;
            cardid |= uid[2];  
            cardid <<= 8;
            cardid |= uid[3]; 
            Serial.print("Seems to be a Mifare Classic card 11111111111 #");
            Serial.println(cardid);
             
         if (success)
         {
           Serial.println("Sector 1 (Blocks 4..7) has been authenticated");
           uint8_t data[16];
         }
       }
     }
   }
   
   void loop() {
   
     time = millis();
     String measurement = "";
     currtouched = cap.touched();
     pmap = SD.open("pmap.txt", FILE_WRITE);
     
     for (uint8_t i=0; i<12; i++) {
       
       if ((currtouched & _BV(i)) && !(lasttouched & _BV(i))) {
         Serial.print(i); Serial.print(" touched at "); Serial.println(time);
         if (i == 5){
           left = left + " " + time;
         }
   
         else if (i == 9){
           right = right + " " + time;
         }
       }
       
       if (!(currtouched & _BV(i)) && (lasttouched & _BV(i))) {
         Serial.print(i); Serial.print(" released at "); Serial.println(time);
   
         if (i == 5){
           left = left + " " + time;  
         }
   
         else if (i == 9){
           right = right + " " + time;
         }
       }
     }
     
     for (int i = Rows-1; i >= 0 ; i--) { 
                                     
      digitalWrite (dPin[i], HIGH);
     
      for (int m = Cols-1; m >= 0 ; m--) {
        sensorValue[m] = analogRead (Pin[m]) * Level;
        if (sensorValue[m] < 50) {
            sensorValue[m] = 0;  
         }
         
        msensorValue[m] = map (sensorValue[m], 0, 1024, 255, 0);
        measurement = measurement + "a" + sensorValue[m];
      }
      digitalWrite (dPin[i], LOW);
     }
   
     Serial.println(measurement);
     if(pmap){
       pmap.println(measurement);
     }
     count++;
     lasttouched = currtouched;
     pmap.close();

     if(time > 10000 && finalise == 0){
       finalise++;
       Serial.println(left);
       Serial.println(right);

       MQTT_connect();
       MQTT_publishMethod(left, ".bench-left");
       MQTT_publishMethod(right, ".bench-right");

       pmap = SD.open("pmap.txt", FILE_READ);

       char character;
       String mapRead = "";
       int q = 0;
         
       if (pmap) {
       
         while (((character = pmap.read()) != -1)) {
           mapRead = mapRead + character;
           q++;
 
           if(q >= 100){
 
           MQTT_publishMethod(mapRead, ".bench-seat");
 
           delay(5000);
           q = 0;
           mapRead = "";  
           }
         }
       } else {
         Serial.println("Could not read.");
         }
                
       resetFunc();
      }
     }
     
   void MQTT_connect() {
     int8_t ret;
   
     while (WiFi.status() != WL_CONNECTED) {
       Serial.print("Attempting to connect to SSID: ");
       Serial.println(ssid);
       status = WiFi.begin(ssid, pass);
   
       uint8_t timeout = 10;
       while (timeout && (WiFi.status() != WL_CONNECTED)) {
         timeout--;
         delay(1000);
       }
     }
     
     if (mqtt.connected()) {
       return;
     }
   
     Serial.print("Connecting to MQTT... ");
   
     while ((ret = mqtt.connect()) != 0) {
          Serial.println(mqtt.connectErrorString(ret));
          Serial.println("Retrying MQTT connection in 5 seconds...");
          mqtt.disconnect();
          delay(5000);
     }
     Serial.println("MQTT Connected!");
   }


   void MQTT_publishMethod(String input, String feed){
     
     String baseUrl = "baynesstua/feeds/";
   
     String feedUrl = baseUrl + "id" + cardid + feed;
     const char* lenChar = feedUrl.c_str();
     int len = strlen(lenChar);
     len++;
     char urlChar[len];
     feedUrl.toCharArray(urlChar, len); 
     Adafruit_MQTT_Publish obj = Adafruit_MQTT_Publish(&mqtt, urlChar);
     int dataLen = input.length() + 1;
     char dataChar [dataLen];
     input.toCharArray(dataChar, dataLen);
     obj.publish(dataChar);

   }

Arduino_Main_230418_Rebuild.ino (7.77 KB)

Is it too much trouble to follow directions? Use code tags when posting.

Edit your post to add them, using the “</>” button on the editor.

Sorry. As you can probably tell it’s the first time I’ve ever used a forum. I found the article you mentioned and gave it a read.

Also here are links to the exact shields/boards I’ve been using:

WIFI: Adafruit WINC1500 WiFi Shield with PCB Antenna : ID 3653 : $24.95 : Adafruit Industries, Unique & fun DIY electronics and kits
NFC: Adafruit PN532 NFC/RFID Controller Shield for Arduino + Extras : ID 789 : $39.95 : Adafruit Industries, Unique & fun DIY electronics and kits
Capacitive: Adafruit 12-Key Capacitive Touch Sensor Breakout - MPR121 [STEMMA QT] : ID 1982 : $7.95 : Adafruit Industries, Unique & fun DIY electronics and kits

Your description of the problem is very vague, and you will have to be a bit more clear.

For example, what does the following line mean?

When I attempt to publish to Adafruit the maximum size char array that will send is 100 characters/bytes

"Adafruit" is a company that sells various hobby electronics components.

What, exactly, are you trying to do? What line of code is failing, and what is the error message?

Sorry it should say Adafruit IO which is their database with and API that allows you to transfer Arduino data over WIFI. I have read it has a 1KB limit per post. Each pressure map reading is 256 numbers with delimiters between so it's more or less twice what I require.

Using Adafruit IO's MQTT API I am trying to post approximately 500 byte Char arrays to this database but it is not allowing me to post more than 100 bytes at a time. (line 235 of my code you can see if(q = 100) 100 being the number of chars it attempts to post. If that is set to over 100 the Arduino resets during the publishing.

Could it be that the WIFI drops out causing the Arduino to reset before finishing the post?

When debugging the MQTT POSTs look like this:

MQTT Connected!
MQTT publish packet:
 0 [0x30], % [0x25],   [0x00], # [0x23], b [0x62], a [0x61], y [0x79], n [0x6E], 
 e [0x65], s [0x73], s [0x73], t [0x74], u [0x75], a [0x61], / [0x2F], g [0x67], 
 r [0x72], o [0x6F], u [0x75], p [0x70], s [0x73], / [0x2F], I [0x49], D [0x44], 
 4 [0x34], 6 [0x36], 8 [0x38], 1 [0x31], . [0x2E], b [0x62], e [0x65], n [0x6E], 
 c [0x63], h [0x68], - [0x2D], l [0x6C], e [0x65], f [0x66], t [0x74], 
Client sendPacket returned: 39

But when they fail they end like this:

[0x61], 0 [0x30], a [⸮WI

with WI indicating that the Arduino has reset.

You will have to break your transmissions down into smaller pieces.

I doubt that the problem is related to your use of String objects, but you have a lot in that code, which [u]will[/u] cause memory problems and eventual crashes. With AVR-based Arduino boards, it is strongly recommended to avoid Strings completely, and use C-strings (character arrays) instead.

Okay thank you for your help.

My professor looked into it today as well and believes it may be related to a stack overflow problem. We may look at replacing the Mega with a Due though there don't seem to be many in stock other than on Ali Express.

Again, thank you for your help and putting up with my bad posting.

Here are the changes I made to enable use of large MQTT messages. This setup seems to work pretty well, although it locks up in mqtt.publish() after 5000-20000 messages.

Adafruit_MQTT.h - Change the value of MAXBUFFERSIZE to a size suitable for your message size. I am getting good results with 1000.

Adafruit_MQTT_Client.cpp - Adafruit_MQTT_Client::sendPacket() modified to eliminate limit on packet size, i.e. replaced: uint16_t sendlen = len > 250 ? 250 : len; with: uint16_t sendlen = len;

Adafruit_MQTT.cpp - Adafruit_MQTT::readFullPacket() changed rLen from uint8_t to uint16_t

Hope that helps!

  • Jack