Browse Source

dev in progress

FloKra 6 years ago
parent
commit
4d20fd771e

+ 11 - 1
src/WiFiSwitch/Buttonhandling.ino

@@ -13,7 +13,17 @@ void buttonAction(byte relnr) {
 }
 
 void buttonHoldAction(byte btn) {
-  mqttclient.publish(mqtt_topic_out_hold[btn], mqtt_payload_out_hold[btn]);
+  switch(btn) {
+    case 0:
+      mqttclient.publish(mqtt_topic_out_hold_1, mqtt_payload_out_hold_1);
+      break;
+    case 1:
+      mqttclient.publish(mqtt_topic_out_hold_2, mqtt_payload_out_hold_2);
+      break;
+    case 2:
+      mqttclient.publish(mqtt_topic_out_hold_3, mqtt_payload_out_hold_3);
+      break;
+  }
 }
 
 void checkButtonStates() {

+ 33 - 14
src/WiFiSwitch/WiFiSwitch.ino

@@ -73,15 +73,21 @@
 
 
 // config variables - do not change here!
-const char* deviceName = DEVICE_NAME;
-const char* mqtt_server = MQTT_SERVER;
+char* deviceName = "123456789012345678901234567890"; // 30 chars
+char* mqtt_server = "123456789012345678901234567890"; // 30 chars
 int mqtt_port = MQTT_PORT;
-const char* mqtt_topic_in = MQTT_TOPIC_IN;
-const char* mqtt_topic_out = MQTT_TOPIC_OUT;
-const char* mqtt_topic_out_hold[3] = { BUTTON1_HOLD_TOPIC_OUT, BUTTON2_HOLD_TOPIC_OUT, BUTTON3_HOLD_TOPIC_OUT };
-const char* mqtt_payload_out_hold[3] = { BUTTON1_HOLD_PAYLOAD_OUT, BUTTON2_HOLD_PAYLOAD_OUT, BUTTON3_HOLD_PAYLOAD_OUT };
+char* mqtt_topic_in = "123456789012345678901234567890"; // 30 chars
+char* mqtt_topic_out = "123456789012345678901234567890"; // 30 chars
+char* mqtt_topic_out_hold_1 = "123456789012345678901234567890"; // 30 chars
+char* mqtt_topic_out_hold_2 = "123456789012345678901234567890"; // 30 chars
+char* mqtt_topic_out_hold_3 = "123456789012345678901234567890"; // 30 chars
+//char* mqtt_payload_out_hold[3] = { BUTTON1_HOLD_PAYLOAD_OUT, BUTTON2_HOLD_PAYLOAD_OUT, BUTTON3_HOLD_PAYLOAD_OUT };
+char* mqtt_payload_out_hold_1 = "123456789012345678901234567890"; // 30 chars
+char* mqtt_payload_out_hold_2 = "123456789012345678901234567890"; // 30 chars
+char* mqtt_payload_out_hold_3 = "123456789012345678901234567890"; // 30 chars
 int domoticzIdx[3] = {DOMOTICZ_IDX_1, DOMOTICZ_IDX_2, DOMOTICZ_IDX_3}; // initially set to 0, must be defined in config
-const char* domoticz_out_topic = DOMOTICZ_OUT_TOPIC; // changeable subscription topic, as domoticz supports different flat/hierarchical out-topics
+char* domoticz_out_topic = "123456789012345678901234567890"; // 30 chars
+
 int relais_impulse[3] = {RELAIS1_IMPULSE, RELAIS2_IMPULSE, RELAIS3_IMPULSE};
 
 // global variables
@@ -151,11 +157,24 @@ void setup() {
     return;
   }
 
-  if (!loadConfig()) {
-    Serial.println("Failed to load config");
-  } else {
-    Serial.println("Config loaded");
-  }
+  deviceName = DEVICE_NAME;
+  mqtt_server = MQTT_SERVER;
+  mqtt_topic_in = MQTT_TOPIC_IN;
+  mqtt_topic_out = MQTT_TOPIC_OUT;
+  mqtt_topic_out_hold_1 = BUTTON1_HOLD_TOPIC_OUT;
+  mqtt_topic_out_hold_2 = BUTTON2_HOLD_TOPIC_OUT;
+  mqtt_topic_out_hold_3 = BUTTON3_HOLD_TOPIC_OUT;
+  mqtt_payload_out_hold_1 = BUTTON1_HOLD_PAYLOAD_OUT;
+  mqtt_payload_out_hold_2 = BUTTON2_HOLD_PAYLOAD_OUT;
+  mqtt_payload_out_hold_3 = BUTTON3_HOLD_PAYLOAD_OUT;
+  domoticz_out_topic = DOMOTICZ_OUT_TOPIC; // changeable subscription topic, as domoticz supports different flat/hierarchical out-topics
+
+  //  if (!loadConfig()) {
+  //    Serial.println("Failed to load config");
+  //  } else {
+  //    Serial.println("Config loaded");
+  //  }
+
 
   // set relais pin modes
   for (int i = 0; i < RELAIS_COUNT; i++) {
@@ -212,7 +231,7 @@ void loop() {
   relais_handleImpulseTimeout();
 
   //everySecond();
-  
+
   persWM.handleWiFi(); //in non-blocking mode, handleWiFi must be called in the main loop
 
   dnsServer.processNextRequest();
@@ -230,6 +249,6 @@ void loop() {
 
   if (Serial.available()) serialEvent();
 
-  delay(50); // save energy by sleeping
+  //delay(50); // save energy by sleeping
 } //void loop
 

+ 110 - 46
src/WiFiSwitch/commands.ino

@@ -12,8 +12,8 @@ void serialEvent() {
     serBuffer[serBufferCount] = '\0'; // string nullterminieren
     Serial.print("serial cmd: ");
     Serial.println(serBuffer);
-    strcpy(cmdPayload,serBuffer);
-    cmdInQueue=true;
+    strcpy(cmdPayload, serBuffer);
+    cmdInQueue = true;
     evalCmd();
     serBufferCount = 0;
   }
@@ -26,7 +26,7 @@ void evalCmd() {
 
     //Serial.print("cmdPayload: ");
     //Serial.println(cmdPayload);
-    
+
     if (strncmp(cmdPayload, "toggle ", 7) == 0) {
       char inValue[1];
       inValue[0] = (char)cmdPayload[7];
@@ -57,59 +57,123 @@ void evalCmd() {
       }
     }
 
+    else if (strncmp(cmdPayload, "loadconf", 8) == 0) {
+      loadConfig();
+    }
+    
     else if (strncmp(cmdPayload, "set ", 4) == 0) {
-      if (strncmp(cmdPayload, "set mqtthost ", 13) == 0) {
-        char buf[50];
-        int len = strlen(cmdPayload) - 13;
-        for (int i=0; i < len; i++) {
-          buf[i] = cmdPayload[i + 13];
-        }
-        buf[len-1]='\0';
-        Serial.print("MQTT host: '");
-        Serial.print(buf);
-        Serial.println("' set");
-      }
-      else if (strncmp(cmdPayload, "set mqttport ", 13) == 0) {
-        char buf[50];
-        int len = strlen(cmdPayload) - 13;
-        for (int i=0; i < len; i++) {
-          buf[i] = cmdPayload[i + 13];
-        }
-        buf[len-1]='\0';
-        Serial.print("MQTT port: '");
-        Serial.print(buf);
-        Serial.println("' set");
+      char buf[80];
+      char setconfCmd[16];
+      char setconfPayload[62];
+
+      int len = strlen(cmdPayload) - 4;
+      for (int i = 0; i < len; i++) {
+        buf[i] = cmdPayload[i + 4];
       }
-      else if (strncmp(cmdPayload, "set wifissid ", 13) == 0) {
-        char buf[50];
-        int len = strlen(cmdPayload) - 13;
-        for (int i=0; i < len; i++) {
-          buf[i] = cmdPayload[i + 13];
-        }
-        buf[len-1]='\0';
-        Serial.print("WiFi SSID: '");
-        Serial.print(buf);
-        Serial.println("' set");
+      buf[len - 1] = '\0';
+
+      //      Serial.print("Buf: ");
+      //      Serial.println(buf);
+
+      int setconfCmdLen = 0;
+      for (int i = 0; i < len; i++) {
+        if (buf[i] == 32 || buf[i] == '\0') break; // if SPACE command name is finished, if \0 command parameter is missing
+        setconfCmd[i] = buf[i];
+        setconfCmdLen++;
       }
-      else if (strncmp(cmdPayload, "set wifipass ", 13) == 0) {
-        char buf[50];
-        int len = strlen(cmdPayload) - 13;
-        for (int i=0; i < len; i++) {
-          buf[i] = cmdPayload[i + 13];
-        }
-        buf[len-1]='\0';
-        Serial.print("WiFi Password: '");
-        Serial.print(buf);
-        Serial.println("' set");
+      setconfCmd[setconfCmdLen] = '\0';
+      //Serial.print("setconfCmdLen: ");
+      //Serial.println(setconfCmdLen);
+
+      //      Serial.print("setconf '");
+      //      Serial.print(setconfCmd);
+
+      int setconfPayloadLen = 0;
+      for (int i = 0; i < len; i++) {
+        if (buf[i + setconfCmdLen + 1] == 32 || buf[i + setconfCmdLen + 1] == '\0') break; // if SPACE command name is finished, if \0 command parameter is missing
+        setconfPayload[i] = buf[i + setconfCmdLen + 1];
+        setconfPayloadLen++;
       }
+      setconfPayload[setconfPayloadLen] = '\0';
+      //Serial.print("setconfPayloadLen: ");
+      //Serial.println(setconfPayloadLen);
+
+      //      Serial.print("' to value '");
+      //      Serial.print(setconfPayload);
+      //      Serial.println("'");
+
+      setConfig(setconfCmd, setconfPayload);
+
+
+      //
+      //
+      //
+      //
+      //
+      //      if (strncmp(cmdPayload, "mqtthost ", 13) == 0) {
+      //        char buf[50];
+      //        int len = strlen(cmdPayload) - 13;
+      //        for (int i = 0; i < len; i++) {
+      //          buf[i] = cmdPayload[i + 13];
+      //        }
+      //        buf[len - 1] = '\0';
+      //        Serial.print("MQTT host: '");
+      //        Serial.print(buf);
+      //        Serial.println("' set");
+      //      }
+      //
+      //
+      //      else if (strncmp(cmdPayload, "set mqttport ", 13) == 0) {
+      //        char buf[50];
+      //        int len = strlen(cmdPayload) - 13;
+      //        for (int i = 0; i < len; i++) {
+      //          buf[i] = cmdPayload[i + 13];
+      //        }
+      //        buf[len - 1] = '\0';
+      //        Serial.print("MQTT port: '");
+      //        Serial.print(buf);
+      //        Serial.println("' set");
+      //      }
+      //      else if (strncmp(cmdPayload, "set wifissid ", 13) == 0) {
+      //        char buf[50];
+      //        int len = strlen(cmdPayload) - 13;
+      //        for (int i = 0; i < len; i++) {
+      //          buf[i] = cmdPayload[i + 13];
+      //        }
+      //        buf[len - 1] = '\0';
+      //        Serial.print("WiFi SSID: '");
+      //        Serial.print(buf);
+      //        Serial.println("' set");
+      //      }
+      //      else if (strncmp(cmdPayload, "set wifipass ", 13) == 0) {
+      //        char buf[50];
+      //        int len = strlen(cmdPayload) - 13;
+      //        for (int i = 0; i < len; i++) {
+      //          buf[i] = cmdPayload[i + 13];
+      //        }
+      //        buf[len - 1] = '\0';
+      //        Serial.print("WiFi Password: '");
+      //        Serial.print(buf);
+      //        Serial.println("' set");
+      //      }
     }
     else if (strncmp(cmdPayload, "restart", 7) == 0) {
       Serial.print("restarting...");
       ESP.restart();
     }
+    else if (strncmp(cmdPayload, "save", 4) == 0) {
+      saveConfig();
+      Serial.println("saved config to SPIFFS");
+      Serial.println("reloading config to check...");
+      loadConfig();
+    }
+    else if (strncmp(cmdPayload, "getconf", 7) == 0) {
+      getConfig();
+    }
+
 
-    
 
     cmdInQueue = false;
   }
-}
+}
+

+ 166 - 58
src/WiFiSwitch/config.ino

@@ -32,7 +32,7 @@ bool loadConfig() {
   // use configFile.readString instead.
   configFile.readBytes(buf.get(), size);
 
-  StaticJsonBuffer<200> jsonBuffer;
+  StaticJsonBuffer<1000> jsonBuffer;
   JsonObject& json = jsonBuffer.parseObject(buf.get());
 
   if (!json.success()) {
@@ -40,78 +40,186 @@ bool loadConfig() {
     return false;
   }
 
-  deviceName = json["deviceName"];
-  mqtt_server = json["mqtt_server"];
-  mqtt_port = atoi(json["mqtt_port"]);
-  mqtt_topic_in = json["mqtt_topic_in"];
-  mqtt_topic_out = json["mqtt_topic_out"];
-  mqtt_topic_out_hold[0] = json["mqtt_topic_out_hold_1"];
-  mqtt_topic_out_hold[1] = json["mqtt_topic_out_hold_2"];
-  mqtt_topic_out_hold[2] = json["mqtt_topic_out_hold_3"];
-  mqtt_payload_out_hold[0] = json["mqtt_payload_out_hold_1"];
-  mqtt_payload_out_hold[1] = json["mqtt_payload_out_hold_2"];
-  mqtt_payload_out_hold[2] = json["mqtt_payload_out_hold_3"];
-  domoticzIdx[0] = atoi(json["domoticzIdx_1"]);
-  domoticzIdx[1] = atoi(json["domoticzIdx_2"]);
-  domoticzIdx[2] = atoi(json["domoticzIdx_3"]);
+  strcpy(deviceName, json["devName"]);
+  strcpy(mqtt_server, json["mqttHost"]);
+  mqtt_port = atoi(json["mqttPort"]);
+  strcpy(mqtt_topic_in, json["inTop"]);
+  strcpy(mqtt_topic_out, json["outTop"]);
+  strcpy(mqtt_topic_out_hold_1, json["outTop_hold1"]);
+  strcpy(mqtt_topic_out_hold_2, json["outTop_hold2"]);
+  strcpy(mqtt_topic_out_hold_3, json["outTop_hold3"]);
+  strcpy(mqtt_payload_out_hold_1, json["outPld_hold1"]);
+  strcpy(mqtt_payload_out_hold_2, json["outPld_hold2"]);
+  strcpy(mqtt_payload_out_hold_3, json["outPld_hold3"]);
+  domoticzIdx[0] = atoi(json["domoIdx1"]);
+  domoticzIdx[1] = atoi(json["domoIdx2"]);
+  domoticzIdx[2] = atoi(json["domoIdx3"]);
+  strcpy(domoticz_out_topic, json["domoOutTop"]);
+  relais_impulse[0] = atoi(json["impuls1"]);
+  relais_impulse[1] = atoi(json["impuls2"]);
+  relais_impulse[2] = atoi(json["impuls3"]);
+
+
+  //  deviceName = json["devName"];
+  //  mqtt_server = json["mqttHost"];
+  //  mqtt_port = atoi(json["mqttPort"]);
+  //  mqtt_topic_in = json["inTop"];
+  //  mqtt_topic_out = json["outTop"];
+  //  mqtt_topic_out_hold[0] = json["outTop_hold1"];
+  //  mqtt_topic_out_hold[1] = json["outTop_hold2"];
+  //  mqtt_topic_out_hold[2] = json["outTop_hold3"];
+  //  mqtt_payload_out_hold[0] = json["outPld_hold1"];
+  //  mqtt_payload_out_hold[1] = json["outPld_hold2"];
+  //  mqtt_payload_out_hold[2] = json["outPld_hold3"];
+  //  domoticzIdx[0] = atoi(json["domoIdx1"]);
+  //  domoticzIdx[1] = atoi(json["domoIdx2"]);
+  //  domoticzIdx[2] = atoi(json["domoIdx3"]);
+  //  domoticz_out_topic = json["domoOutTop"];
+  //  relais_impulse[0] = json["impuls1"];
+  //  relais_impulse[1] = json["impuls2"];
+  //  relais_impulse[2] = json["impuls3"];
 
   Serial.println("Loaded config values:");
-  Serial.print("mqtt_server: ");
+  getConfig();
+  return true;
+}
+
+void getConfig() {
+  Serial.print("devName: ");
+  Serial.println(deviceName);
+  Serial.print("mqttHost: ");
   Serial.println(mqtt_server);
-  Serial.print("mqtt_port: ");
+  Serial.print("mqttPort: ");
   Serial.println(mqtt_port);
-  Serial.print("mqtt_topic_in: ");
+  Serial.print("inTop: ");
   Serial.println(mqtt_topic_in);
-  Serial.print("mqtt_topic_out: ");
+  Serial.print("outTop: ");
   Serial.println(mqtt_topic_out);
-  Serial.print("mqtt_topic_out_hold_1: ");
-  Serial.println(mqtt_topic_out_hold[0]);
-  Serial.print("mqtt_topic_out_hold_2: ");
-  Serial.println(mqtt_topic_out_hold[1]);
-  Serial.print("mqtt_topic_out_hold_3: ");
-  Serial.println(mqtt_topic_out_hold[2]);
-  Serial.print("mqtt_payload_out_hold_1: ");
-  Serial.println(mqtt_payload_out_hold[0]);
-  Serial.print("mqtt_payload_out_hold_2: ");
-  Serial.println(mqtt_payload_out_hold[1]);
-  Serial.print("mqtt_payload_out_hold_3: ");
-  Serial.println(mqtt_payload_out_hold[2]);
-  Serial.print("domoticzIdx_1: ");
+  Serial.print("outTop_hold1: ");
+  Serial.println(mqtt_topic_out_hold_1);
+  Serial.print("outTop_hold2: ");
+  Serial.println(mqtt_topic_out_hold_2);
+  Serial.print("outTop_hold3: ");
+  Serial.println(mqtt_topic_out_hold_3);
+  Serial.print("outPld_hold1: ");
+  Serial.println(mqtt_payload_out_hold_1);
+  Serial.print("outPld_hold2: ");
+  Serial.println(mqtt_payload_out_hold_2);
+  Serial.print("outPld_hold3: ");
+  Serial.println(mqtt_payload_out_hold_3);
+  Serial.print("domoIdx1: ");
   Serial.println(domoticzIdx[0]);
-  Serial.print("domoticzIdx_2: ");
+  Serial.print("domoIdx2: ");
   Serial.println(domoticzIdx[1]);
-  Serial.print("domoticzIdx_3: ");
+  Serial.print("domoIdx3: ");
   Serial.println(domoticzIdx[2]);
-//  Serial.print(": ");
-//  Serial.println();
-//  Serial.print(": ");
-//  Serial.println();
-//  Serial.print(": ");
-//  Serial.println();
-  return true;
+  Serial.print("domoOutTop: ");
+  Serial.println(domoticz_out_topic);
+  Serial.print("impuls1: ");
+  Serial.println(relais_impulse[0]);
+  Serial.print("impuls2: ");
+  Serial.println(relais_impulse[1]);
+  Serial.print("impuls3: ");
+  Serial.println(relais_impulse[2]);
 }
 
 
+bool setConfig(char* param, char* value) {
+
+//  char buf[80];
+//  int len = strlen(value);
+//  for (int i = 0; i < len; i++) {
+//    buf[i] = value[i];
+//  }
+//  buf[len] = '\0';
+
+  Serial.print("param: ");
+  Serial.print(param);
+  Serial.print(", value: ");
+  Serial.println(value);
+
+  if ( strcmp(param, "devName") == 0 ) {
+    strcpy(deviceName, value);
+  }
+  else if ( strcmp(param, "mqttHost") == 0 ) {
+    strcpy(mqtt_server, value);
+  }
+    else if ( strcmp(param, "mqttPort") == 0 ) {
+      mqtt_port = atoi(value);
+    }
+    else if ( strcmp(param, "inTop") == 0 ) {
+      strcpy(mqtt_topic_in, value);
+    }
+    else if ( strcmp(param, "outTop") == 0 ) {
+      strcpy(mqtt_topic_out, value);
+    }
+    else if ( strcmp(param, "outTop_hold1") == 0 ) {
+      strcpy(mqtt_topic_out_hold_1, value);
+    }
+    else if ( strcmp(param, "outTop_hold2") == 0 ) {
+      strcpy(mqtt_topic_out_hold_2, value);
+    }
+    else if ( strcmp(param, "outTop_hold3") == 0 ) {
+      strcpy(mqtt_topic_out_hold_3, value);
+    }
+    else if ( strcmp(param, "outPld_hold1") == 0 ) {
+      Serial.print("set outPld_hold1");
+      strcpy(mqtt_payload_out_hold_1, value);
+    }
+    else if ( strcmp(param, "outPld_hold2") == 0 ) {
+      Serial.print("set outPld_hold2");
+      strcpy(mqtt_payload_out_hold_2, value);
+    }
+    else if ( strcmp(param, "outPld_hold3") == 0 ) {
+      Serial.print("set outPld_hold3");
+      strcpy(mqtt_payload_out_hold_3, value);
+    }
+    else if ( strcmp(param, "domoIdx1") == 0 ) {
+      domoticzIdx[0] = atoi(value);
+    }
+    else if ( strcmp(param, "domoIdx2") == 0 ) {
+      domoticzIdx[1] = atoi(value);
+    }
+    else if ( strcmp(param, "domoIdx3") == 0 ) {
+      domoticzIdx[2] = atoi(value);
+    }
+    else if ( strcmp(param, "domoOutTop") == 0 ) {
+      strcpy(domoticz_out_topic, value);
+    }
+    else if ( strcmp(param, "impuls1") == 0 ) {
+      relais_impulse[0] = atoi(value);
+    }
+    else if ( strcmp(param, "impuls2") == 0 ) {
+      relais_impulse[1] = atoi(value);
+    }
+    else if ( strcmp(param, "impuls3") == 0 ) {
+      relais_impulse[2] = atoi(value);
+    }
+}
+
 
 bool saveConfig() {
-  StaticJsonBuffer<200> jsonBuffer;
+  StaticJsonBuffer<1000> jsonBuffer;
   JsonObject& json = jsonBuffer.createObject();
-  
-  json["deviceName"] = deviceName;
-  json["mqtt_server"] = mqtt_server;
-  json["mqtt_port"] = mqtt_port;
-  json["mqtt_topic_in"] = mqtt_topic_in;
-  json["mqtt_topic_out"] = mqtt_topic_out;
-  json["mqtt_topic_out_hold_1"] = mqtt_topic_out_hold[0];
-  json["mqtt_topic_out_hold_2"] = mqtt_topic_out_hold[1];
-  json["mqtt_topic_out_hold_3"] = mqtt_topic_out_hold[2];
-  json["mqtt_payload_out_hold_1"] = mqtt_payload_out_hold[0];
-  json["mqtt_payload_out_hold_2"] = mqtt_payload_out_hold[1];
-  json["mqtt_payload_out_hold_3"] = mqtt_payload_out_hold[2];
-  json["domoticzIdx_1"] = domoticzIdx[0];
-  json["domoticzIdx_2"] = domoticzIdx[1];
-  json["domoticzIdx_3"] = domoticzIdx[2]; 
-  
+
+  json["devName"] = deviceName;
+  json["mqttHost"] = mqtt_server;
+  json["mqttPort"] = mqtt_port;
+  json["inTop"] = mqtt_topic_in;
+  json["outTop"] = mqtt_topic_out;
+  json["outTop_hold1"] = mqtt_topic_out_hold_1;
+  json["outTop_hold2"] = mqtt_topic_out_hold_2;
+  json["outTop_hold3"] = mqtt_topic_out_hold_3;
+  json["outPld_hold1"] = mqtt_payload_out_hold_1;
+  json["outPld_hold2"] = mqtt_payload_out_hold_2;
+  json["outPld_hold3"] = mqtt_payload_out_hold_3;
+  json["domoIdx1"] = domoticzIdx[0];
+  json["domoIdx2"] = domoticzIdx[1];
+  json["domoIdx3"] = domoticzIdx[2];
+  json["domoOutTop"] = domoticz_out_topic;
+  json["impuls1"] = relais_impulse[0];
+  json["impuls2"] = relais_impulse[1];
+  json["impuls3"] = relais_impulse[2];
 
   File configFile = SPIFFS.open("/config.json", "w");
   if (!configFile) {

+ 1 - 1
src/WiFiSwitch/httpServer.ino

@@ -131,7 +131,7 @@ void httpServerInit() {
     json["swState1"] = relais_state[0];
     if(RELAIS_COUNT > 1) json["swState2"] = relais_state[1];
     if(RELAIS_COUNT > 2) json["swState3"] = relais_state[2];
-    json["devname"] = DEVICE_NAME;
+    json["devname"] = deviceName;
     
     char jsonchar[200];
     json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece