Only Send OSC packet with unique value

Hello,

I’m working on an analogue input to OSC sketch and have successfully managed to get data from a pot smooth out the numbers and then wrap all this up in a OSC packet, with the help of some great examples !

Loop being loop obviously sends the packet every time and I was wondering if there was a way that it can look at the analogue ‘average’ each loop and if it is the same not send, if it has changed send the packet.

My current code below

#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>    
#include <OSCMessage.h>

// Define the number of samples to keep track of. The higher the number, the
// more the readings will be smoothed, but the slower the output will respond to
// the input. Using a constant rather than a normal variable lets us use this
// value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int inputPin = A0;


EthernetUDP Udp;

//the Arduino's IP
IPAddress ip(2, 0, 0, 120);
//destination IP
IPAddress outIp(2, 0, 0, 100);
const unsigned int outPort = 9999;

 byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields
void setup() {
  Ethernet.begin(mac,ip);
    Udp.begin(8888);
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }

}


void loop(){

  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(inputPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  delay(1);        // delay in between reads for stability

  
  //the message wants an OSC address as first argument
  OSCMessage msg("/analog/0");
  msg.add((int32_t)int(average));
  
  Udp.beginPacket(outIp, outPort);
    msg.send(Udp); // send the bytes to the SLIP stream
  Udp.endPacket(); // mark the end of the OSC Packet
  msg.empty(); // free space occupied by message


  delay(1);
}

I was wondering if there was a way that it can look at the analogue 'average' each loop and if it is the same not send, if it has changed send the packet.

You can certainly do that

Clumsy way : save the value read and next time you read a value compare it with the previous one. If it has changed significantly (you decide what is significant) then send your message

Better way : use the average of several readings instead of a single one before doing the comparison

Ah good point,
I have adapted it to include the following which seems to work well

#include <Ethernet.h>
#include <EthernetUdp.h>
#include <SPI.h>    
#include <OSCMessage.h>

// Define the number of samples to keep track of. The higher the number, the
// more the readings will be smoothed, but the slower the output will respond to
// the input. Using a constant rather than a normal variable lets us use this
// value to determine the size of the readings array.
const int numReadings = 10;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average
int prev = 0;                       // previous value to compare if changed
int storevalue = 0;

int inputPin = A0;


EthernetUDP Udp;

//the Arduino's IP
IPAddress ip(2, 0, 0, 120);
//destination IP
IPAddress outIp(2, 0, 0, 150);
const unsigned int outPort = 9999;

 byte mac[] = {  
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; // you can find this written on the board of some Arduino Ethernets or shields
void setup() {

    // initialize serial communications at 9600 bps:
  Serial.begin(9600);
  
  Ethernet.begin(mac,ip);
    Udp.begin(8888);
  // initialize all the readings to 0:
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }

}


void loop(){

  // subtract the last reading:
  total = total - readings[readIndex];
  // read from the sensor:
  readings[readIndex] = analogRead(inputPin);
  // add the reading to the total:
  total = total + readings[readIndex];
  // advance to the next position in the array:
  readIndex = readIndex + 1;

  // if we're at the end of the array...
  if (readIndex >= numReadings) {
    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  delay(1);        // delay in between reads for stability

  //store previous value 
  prev = average;
  Serial.println(prev);
  Serial.println(total);

void dataSend();

if (storevalue == prev){

 Serial.println("No new data to send");
 
}
  else
  {

 Serial.println("Send new data");
   //the message wants an OSC address as first argument
  OSCMessage msg("/analog/0");
  msg.add((int32_t)int(average));
  
  Udp.beginPacket(outIp, outPort);
    msg.send(Udp); // send the bytes to the SLIP stream
  Udp.endPacket(); // mark the end of the OSC Packet
  msg.empty(); // free space occupied by message


  delay(1);
    }

storevalue = prev;

}

I’m not great at coding so if there is a more efficient way of doing the above I would be happy for any advice.

(I have left the serial print in so I can see what was going on but that will be removed)
Thanks

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.