Json Command Receiver

Dette eksempel viser hvordan man kan bruge JSON data formatet til at udveksle information med en arduino og sende kommandoer via seriel porten.

Ved at sende en passende kommando kan man ændre på hastighed og duty cycle for en blinkende LED.

For nemt at kunne arbejde med JSON i Arduino koden benyttes biblioteket Arduino JSON. Derfor er det nødvendigt at installere dette på udviklingsmaskinen, inden denne sketch kan kompileres, det klares via. Arduino Library Manager, se hvordan du installerer det her.

#include <ArduinoJson.h>

// Allocate the JSON document
//
// Inside the brackets, 200 is the capacity of the memory pool in bytes.
// Don't forget to change this value to match your JSON document.
// Use arduinojson.org/v6/assistant to compute the capacity.
//  StaticJsonDocument<200> doc;

// StaticJsonDocument<N> allocates memory on the stack, it can be
// replaced by DynamicJsonDocument which allocates in the heap.
//
DynamicJsonDocument doc(200);

int periodMs = 2000;
int dutyPct = 50;

void setup()
{
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(115200);
  // wait for serial port to connect. Needed for native USB
  while (!Serial)
  {
    continue;
  }
  Serial.println("Ready for commands");
}

void loop()
{
  myLedControl();
  parseCommands();
}


// Example of test input json
/* 
{"ts": 1000, "duty": 10 }
 */
void parseCommands()
{
  // reply only when you receive data:
  if (Serial.available() > 0)
  {

    // Deserialize the JSON document
    DeserializationError error = deserializeJson(doc, Serial);

    Serial.println("Received:");
    serializeJson(doc, Serial);
    Serial.println();

    // Test if parsing succeeds.
    if (error)
    {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.c_str());
      return;
    }

    if (doc["ts"])
    {
      unsigned int ts = doc["ts"];
      Serial.print("got ts: ");
      Serial.println(ts);
      periodMs = ts;
    }

    if (doc["duty"])
    {
      int duty = doc["duty"];
      Serial.print("got duty: ");
      Serial.println(duty);
      duty = constrain(duty, 0, 100);
      Serial.print("constrained duty to [0, 100], using: ");
      Serial.println(duty);
      dutyPct = duty;
    }

  }
}

// toggle the builtin LED state
void myLedControl()
{
  //map(value, fromLow, fromHigh, toLow, toHigh)
  int highDelayMs = map(dutyPct, 0, 100, 0, periodMs);
  int lowDelayMs = periodMs - highDelayMs;
  
  digitalWrite(LED_BUILTIN, HIGH);
  delay(highDelayMs);
  digitalWrite(LED_BUILTIN, LOW);
  delay(lowDelayMs);
}

NB! Serielporten er sat til at køre 115200 Baud.

Prøv at sende nogle kommandoer vha. serial monitor, og læg mærke til hvordan blinkrate og duty cycle ændres for den inbyggede LED på Arduino.

{"ts": 1000, "duty": 10 }
{"ts": 500, "duty": 80 }

Når eksemplet køres på en Arduino og de to ovenstående kommandoer sendes en ad gangen, kommer der dette output fra Arduino på seriel porten.

Ready for commands
Received:
{"ts":1000,"duty":10}
got ts: 1000
got duty: 10
constrained duty to [0, 100], using: 10
Received:
{"ts":500,"duty":80}
got ts: 500
got duty: 80
constrained duty to [0, 100], using: 80

Materiale