Hardware components | ||||||
![]() |
| × | 1 | |||
| × | 1 | ||||
All TV's in Europe have a slot called Common Interface.
In this slot you can place a Common Interface Module that typically may have a WiFi antenna.
The CAM WiFi connection will exchange data with Arduino cloud monitoring in real time and keeping track of all the channel changes that a TV viewer would perform during the day.
This system will have big interest for advertising companies that could use a champion of families and, in a non-intrusive way, collect data of the viewing habits.
With the viewing habits, the advertising space has more value and can be sold with real data analysis.
This is what Nielsen is doing with very expensive devices.
I have build a very simple way to manage the E2E integration using: CAM with WiFi and Arduino Cloud!
The project was selected for the Arduino Cloud Games 2022 and was built in less than three weeks, working only during my weekends. The Arduino Cloud Oplà kit and the tutorials on the website were incredibly exhaustive to make any kind of project.
#cloudgames2022 #arduinocloudgames #acg2022
The outcome of the project is a dashboard that you can see on the video.
You can track, every five seconds, the channel that the user is watching.
Close to each channel, there is a percentage widget, that shows the time the user spent watching this channel while the television was switched on.
The green led instead, will tell you in real time which channel the user is watching.
In the center, you can see the current time, the time the measurement started, the time the television in total has been on, a green or a red tag that tell you if the television is on or off, and finally the reset button.
All the data, is stored in a flash SD memory inserted in the carrier module of the Oplà kit. This is necessary for two reasons. First, after you finished monitoring, you can read the data in a PC. Second, in case the Arduino looses power or performs a reset, the data will be reloaded during the boot of the Arduino and continue the monitoring without losing any action of the user.
The reset button is used to reset the monitoring. When you press the reset button, all the data will de deleted from the flash memory and the monitoring will start from scratch.
How does it work?The coding starts from reading the values from the CAM WiFi every 5 seconds.
The CAM WiFi answers to a POST command with a lot of information using JSON format. The information I need is the DVB Triplet (OID, TID, SID) which gives the exact channel the TV is tuned on. There is no duplication of the triplets so you can be sure that the TV is looking to that channel.
The channel that I have selected to monitor are in the Italian DVB-T network. However any broadcast network can be monitored. You just need to modify the code and reflect the DVB Triplet you want to monitor. In my case:
- RAI 1 = 217c 0001 03eb
- RAI 2 = 217c 0002 041c
- RAI 3 = 217c 0002 041b
- etc
You can find the Triplet combination on the internet for any broadcast channel.
Once you know on which channel the TV is tuned on, the application stores the amount of seconds the channel is viewed and sends the data to the Arduino Cloud. This is then recorded to the dashboard and gives an update every 5 seconds.
mDNSThe CAM WiFi is found by the Arduino MKR WiFi 1010 using the mDNS protocol (bonjour). Libraries created by Georg Kaindl and then modified by Khoi Hoang. This library was important because the CAM WiFi can change the IP Address or because there may be more than one CAM WiFi in the home network. With my software any CAM WiFi will contribute to the dashboard.
JSON dataThe CAM WiFi answers to the POST command in JSON format. To parse the data received by the CAM WiFi, I used the Arduinojson library. After receiving the data I have done a HASH to the DVB triplet and then used the a "case" function to determine the channel the TV was tuned on. The HASH was necessary so that I could use the integer value instead of the HEX one.
The TV channels recognized in my application are 9. For all the other channels I created a category called "Other Channels". However, modifying the source code, you can add more channels if needed.
Hope you enjoy it. If you have questions happy to answer.
Arduino Audience Measurement
Arduino/***************************************************************************************************
Arduino Audience Measurement
Sketch created by Carlo Stramaglia for the Arduino Cloud Games. My pitch has been selected on
Jan 26th 2022.
This sketch aims to measure the behaviur of users while watching Television.
Please check on my youtube channel https://www.youtube.com/c/CarloStramaglia for latest projects
Project start date: Jan 30th 2022
Project end date: March 11th 2022
Location: Monza (Italy)
Board: Arduino MKR WiFi 1010 (Opl Kit)
Device: CAM WiFi see www.camwifi.it for more info
Thanks to mDNS library (Georg Kaindl) for the IP discovery section
****************************************************************************************************/
#include "thingProperties.h"
#include <ArduinoHttpClient.h>
#include "defines.h"
#include <ArduinoJson.h>
#include <Arduino_MKRIoTCarrier.h> //Inserted 19-1
MKRIoTCarrier carrier; //Inserted 19-1
String hostname = BOARD_TYPE;
WiFiUDP udp;
#include <MDNS_Generic.h>
int status = WL_IDLE_STATUS; // the Wifi radio's status
MDNS mdns(udp);
IPAddress foundIP;
int canale = 1;
uint32_t myCustomColor = carrier.leds.Color(255,100,50);// inserted 19-1
File audience;
const unsigned long RAI1 = 2283498029; // RAI1 triplet hashed
const unsigned long RAI2 = 2284683324; // RAI2 triplet hashed
const unsigned long RAI3 = 2284683323; // RAI3 triplet hashed
const unsigned long RETE4 = 846798962; // Rete4 triplet hashed
const unsigned long CANALE5 = 846798963; // Canale 5 triplet hashed
const unsigned long ITALIA1 = 846798964; // Italia 1 triplet hashed
const unsigned long LA7 = 3582080439; // La7 triplet hashed
const unsigned long TV8 = 3540717605; // TV 8 triplet hashed
const unsigned long NOVE = 3045597136; // Canale 9 triplet hashed
float cRai1 = 0, cRai2 = 0, cGlobal = 0, cRai3 = 0, cRete4 = 0, cCanale5 = 0, cItalia1 = 0, cLa7 = 0, cTv8 = 0, cNove = 0, cUnknown = 0;
char serverAddress[20] = " "; // CAM WiFi Address. Initially blank.
int port = 24666; // CAM WiFi Port
WiFiClient wifia;
void printWifiStatus()
{
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("Signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
void serviceFound(const char* type, MDNSServiceProtocol /*proto*/,
const char* name, IPAddress ip,
unsigned short port,
const char* txtContent)
{
if (NULL == name)
{
Serial.print("Finished discovering services of type ");
Serial.println(type);
}
else
{
foundIP=ip;
sprintf(serverAddress, "%d.%d.%d.%d", foundIP[0], foundIP[1], foundIP[2],foundIP[3]);
Serial.print("Found: '");
Serial.print(name);
Serial.print("' at ");
Serial.print(ip);
Serial.print(", port ");
Serial.print(port);
Serial.println(" (TCP)");
if (txtContent)
{
Serial.print("\ttxt record: ");
char buf[256];
char len = *txtContent++;
int i = 0;
while (len)
{
i = 0;
while (len--)
buf[i++] = *txtContent++;
buf[i] = '\0';
Serial.print(buf);
len = *txtContent++;
if (len)
Serial.print(", ");
else
Serial.println();
}
}
}
}
void setup() {
//CARRIER_CASE = false;
char inputdata[1] = {0x20};
char datachar[20];
unsigned long Fposition;
Serial.begin(9600);
delay(1500);
if (!carrier.begin())
{
Serial.println("Carrier not connected, check connections");
while (1);
}
carrier.leds.setBrightness(30);
// carrier.leds.fill(myCustomColor, 0, 5);
// carrier.leds.show();
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information youll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(0);
ArduinoCloud.printDebugInfo();
Serial.print("\nStart WiFiDiscoveringServices on "); Serial.println(BOARD_NAME);
Serial.println(MDNS_GENERIC_VERSION);
Serial.print("Attempting to connect to SSID: "); Serial.println(SSID);
WiFi.begin(SSID, PASS);
delay(1000);
// attempt to connect to Wifi network:
while (status != WL_CONNECTED)
{
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.status();
delay(1000);
}
printWifiStatus();
hostname.toLowerCase();
hostname.replace(" ", "-");
hostname.replace("_", "-");
Serial.print("Registering mDNS hostname: "); Serial.println(hostname);
Serial.print("To access, using "); Serial.print(hostname); Serial.println(".local");
mdns.begin(WiFi.localIP(), hostname.c_str());
mdns.setServiceFoundCallback(serviceFound);
Serial.println("Reading audience.txt");
audience = SD.open("audience.txt");
if (audience) {
Serial.println("audience.txt:");
for (int j = 0; j < 12; j++) {
for(int i = 0; inputdata[0] != '\r'; i++){
audience.read(inputdata,1);
datachar[i] = inputdata[0];
}
Fposition = audience.position();
audience.seek(Fposition+1);
inputdata[0] = 0x20;
Serial.println(datachar);
switch (j)
{
case 0:
cGlobal = atof(datachar);
tGlobal = cGlobal-3600;
Serial.print("cGlobal in Float = ");
Serial.println(cGlobal);
break;
case 1:
cRai1 = atof(datachar);
tRai1 = cRai1/cGlobal*100;
Serial.print("cRai1 in Float = ");
Serial.println(cRai1);
break;
case 2:
cRai2 = atof(datachar);
tRai2 = cRai2/cGlobal*100;
Serial.print("cRai2 in Float = ");
Serial.println(cRai2);
break;
case 3:
cRai3 = atof(datachar);
tRai3 = cRai3/cGlobal*100;
Serial.print("cRai3 in Float = ");
Serial.println(cRai3);
break;
case 4:
cRete4 = atof(datachar);
tRete4 = cRete4/cGlobal*100;
Serial.print("cRete4 in Float = ");
Serial.println(cRete4);
break;
case 5:
cCanale5 = atof(datachar);
tCanale5 = cCanale5/cGlobal*100;
Serial.print("cCanale5 in Float = ");
Serial.println(cCanale5);
break;
case 6:
cItalia1 = atof(datachar);
tItalia1 = cItalia1/cGlobal*100;
Serial.print("cItalia1 in Float = ");
Serial.println(cItalia1);
break;
case 7:
cLa7 = atof(datachar);
tLa7 = cLa7/cGlobal*100;
Serial.print("cLa7 in Float = ");
Serial.println(cLa7);
break;
case 8:
cTv8 = atof(datachar);
tTv8 = cTv8/cGlobal*100;
Serial.print("cTv8 in Float = ");
Serial.println(cTv8);
break;
case 9:
cNove = atof(datachar);
tNove = cNove/cGlobal*100;
Serial.print("cNove in Float = ");
Serial.println(cNove);
break;
case 10:
cUnknown = atof(datachar);
tUnknown = cUnknown/cGlobal*100;
Serial.print("cUnknown in Float = ");
Serial.println(cUnknown);
break;
case 11:
startDate = atof(datachar);
Serial.print("startDate = ");
Serial.println(startDate);
break;
}
}
// close the file:
Serial.println("Closing file audience.txt");
audience.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening audience.txt");
}
}
void loop() {
ArduinoCloud.update();
char serviceName[256]="_sdtvwcam"; // Standard name of the CAM WiFi
upTime = WiFi.getTime();
if (serverAddress[0] != 0x20)
{
if (SD.remove("audience.txt") != true)
Serial.println("removal of audience.txt not successful");
audience = SD.open("audience.txt",FILE_WRITE);
if (audience) {
Serial.print("Writing to audience.txt...");
audience.println(cGlobal);
audience.println(cRai1);
audience.println(cRai2);
audience.println(cRai3);
audience.println(cRete4);
audience.println(cCanale5);
audience.println(cItalia1);
audience.println(cLa7);
audience.println(cTv8);
audience.println(cNove);
audience.println(cUnknown);
audience.println(startDate);
// close the file:
audience.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening audience.txt");
}
}
if (serverAddress[0] != 0x20)
{
carrier.leds.fill(myCustomColor, 0, 5);
carrier.leds.show();
tVon = true;
rai1 = false;
rai2 = false;
rai3 = false;
rete4 = false;
canale5 = false;
italia1 = false;
la7 = false;
tv8 = false;
nove = false;
unknownch = false;
}
else
{
carrier.leds.fill(myCustomColor, 0, 1);
carrier.leds.show();
tVon = false;
rai1 = false;
rai2 = false;
rai3 = false;
rete4 = false;
canale5 = false;
italia1 = false;
la7 = false;
tv8 = false;
nove = false;
unknownch = false;
}
// You can use the "isDiscoveringService()" function to find out whether the
// mDNS library is currently discovering service instances.
// If so, we skip this input, since we want our previous request to continue.
if (!mdns.isDiscoveringService())
{
Serial.print("Discovering services of type '");
Serial.print(serviceName);
Serial.println("' via Multi-Cast DNS (Bonjour)...");
mdns.startDiscoveringService(serviceName, MDNSServiceTCP, 5000);
}
if (serverAddress[0] != 0x20)
readChannel();
// This actually runs the mDNS module. YOU HAVE TO CALL THIS PERIODICALLY,
// OR NOTHING WILL WORK!
// Preferably, call it once per loop().
mdns.run();
}
void readChannel() {
DynamicJsonDocument doc(1024);
//DynamicJsonDocument TV(1024);
//char returnFromCAM[500];
char channeltuned[13];
unsigned long chTuned;
char foundOID[4];
Serial.println ("Network IP of CAMWiFi OK!");
Serial.println (cGlobal);
delay (5000);
tRai1 = cRai1/cGlobal*100;
Serial.print("tRai1 = ");
Serial.println(tRai1);
tRai2 = cRai2/cGlobal*100;
Serial.print("tRai2 = ");
Serial.println(tRai2);
tRai3 = cRai3/cGlobal*100;
Serial.print("tRai3 = ");
Serial.println(tRai3);
tRete4 = cRete4/cGlobal*100;
Serial.print("tRete4 = ");
Serial.println(tRete4);
tCanale5 = cCanale5/cGlobal*100;
Serial.print("tCanale5 = ");
Serial.println(tCanale5);
tItalia1 = cItalia1/cGlobal*100;
Serial.print("tItalia1 = ");
Serial.println(tItalia1);
tLa7 = cLa7/cGlobal*100;
Serial.print("tLa7 = ");
Serial.println(tLa7);
tTv8 = cTv8/cGlobal*100;
Serial.print("tTv8 = ");
Serial.println(tTv8);
tNove = cNove/cGlobal*100;
Serial.print("tNove = ");
Serial.println(tNove);
tUnknown = cUnknown/cGlobal*100;
Serial.print("tUnknown = ");
Serial.println(tUnknown);
tGlobal = cGlobal-3600;
upTime = WiFi.getTime();
cGlobal = cGlobal + 5;
String contentType = "application/json";
char postHello[250] = "command:deviceHello,\n\tclientID:wapp,\n sessionID:0090FFA,\n version:2,\n param: {\n }";
HttpClient client = HttpClient(wifia, serverAddress, port);
client.post("/deviceHello", contentType, postHello);
// read the status code and body of the response
int statusCode = client.responseStatusCode();
String returnFromCAM = client.responseBody();
Serial.print("Status code: ");
Serial.println(statusCode);
Serial.print("Response: ");
Serial.println(returnFromCAM);
DeserializationError error = deserializeJson(doc, returnFromCAM);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
const char* command = doc["command"];
int Version = doc["version"];
const char* OID = doc["data"]["TV"]["tuned_on"]["OID"];
const char* TID = doc["data"]["TV"]["tuned_on"]["TID"];
const char* SID = doc["data"]["TV"]["tuned_on"]["SID"];
Serial.println (" ");
Serial.print("Command parsed = ");
Serial.println(command);
Serial.print("Version parsed = ");
Serial.println(Version);
Serial.print("Tuned On = ");
Serial.print(OID);
Serial.print(" ");
Serial.print(TID);
Serial.print(" ");
Serial.print(SID);
Serial.println(" ");
Serial.println(" ");
sprintf(channeltuned,"%s%s%s",OID,TID,SID);
Serial.println(channeltuned);
//chTuned=atoi(channeltuned);
chTuned = hash(channeltuned);
Serial.print("Channel with Hash = ");
Serial.println(chTuned);
switch (chTuned)
{
case RAI1:
Serial.println("RAI 1");
rai1 = true;
cRai1 = cRai1+5;
break;
case RAI2:
Serial.println("RAI 2");
// rai1 = false;
rai2 = true;
cRai2 = cRai2 + 5;
break;
case RAI3:
Serial.println("RAI 3");
rai3 = true;
cRai3 = cRai3 + 5;
break;
case RETE4:
Serial.println("RETE 4");
rete4 = true;
cRete4 = cRete4 + 5;
break;
case CANALE5:
Serial.println("CANALE 5");
canale5 = true;
cCanale5 = cCanale5 + 5;
break;
case ITALIA1:
Serial.println("ITALIA 1");
italia1 = true;
cItalia1 = cItalia1 + 5;
break;
case LA7:
Serial.println("LA7");
la7 = true;
cLa7 = cLa7 + 5;
break;
case TV8:
Serial.println("TV 8");
tv8 = true;
cTv8 = cTv8 + 5;
break;
case NOVE:
Serial.println("CANALE 9");
nove = true;
cNove = cNove + 5;
break;
default:
unknownch = true;
cUnknown = cUnknown + 5;
}
}
unsigned long hash(char *str)
{
unsigned long hash = 5381;
int c;
while (c = *str++)
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash;
}
/*
Since BReset is READ_WRITE variable, onBResetChange() is
executed every time a new value is received from IoT Cloud.
*/
void onBResetChange() {
// Add your code here to act upon BReset change
Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.print("bReset Changed! = ");
Serial.println(bReset);
Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.println();
if (bReset == false)
return;
Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.println("Reset Button Pressed TRUE!");
Serial.println();
Serial.println();
Serial.println();
Serial.println();
Serial.println();
cGlobal = 0.00;
cRai1 = 0.00;
cRai2 = 0.00;
cRai3 = 0.00;
cRete4 = 0.00;
cCanale5 = 0.00;
cItalia1 = 0.00;
cLa7 = 0.00;
cTv8 = 0.00;
cNove = 0.00;
cUnknown = 0.00;
startDate = WiFi.getTime();
}
/****************************************************************************************************************************
defines.h
mDNS library to support mDNS (registering services) and DNS-SD (service discovery).
Based on and modified from https://github.com/arduino-libraries/ArduinoMDNS
Built by Khoi Hoang https://github.com/khoih-prog/MDNS_Generic
Licensed under MIT license
Original Author: Georg Kaindl (http://gkaindl.com)
This file is part of Arduino EthernetBonjour.
EthernetBonjour is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
EthernetBonjour is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with EthernetBonjour.
If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************************************************************/
#ifndef defines_h
#define defines_h
#define SYSTEM_ENDIAN _ENDIAN_BIG_
#define MDNS_DEBUG_PORT Serial
#define _MDNS_LOGLEVEL_ 1
#define DEBUG_WIFININA_PORT Serial
// Debug Level from 0 to 4
#define _WIFININA_LOGLEVEL_ 1
#if defined(ESP32)
#define BOARD_TYPE ARDUINO_BOARD
#define ESP_getChipId() ((uint32_t)ESP.getEfuseMac())
#define WIFI_NETWORK_ESP true
#define WIFI_NETWORK_TYPE WIFI_NETWORK_ESP
#elif defined(ESP8266)
#error ESP8266 not supported. Please use native ESP8266mDNS library
#endif
#if ( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21E18A__) || defined(__SAMD51__) || defined(__SAMD51J20A__) || defined(__SAMD51J19A__) \
|| defined(__SAMD51G19A__) || defined(__SAMD51P19A__) || defined(__SAMD21G18A__) )
#if defined(WIFININA_USE_SAMD)
#undef WIFININA_USE_SAMD
#endif
#define WIFININA_USE_SAMD true
#if defined(ARDUINO_SAMD_ZERO)
#define BOARD_TYPE "SAMD Zero"
#elif defined(ARDUINO_SAMD_MKR1000)
#define BOARD_TYPE "SAMD MKR1000"
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
#define BOARD_TYPE "SAMD MKRWIFI1010"
#define WIFI_NETWORK_WIFI101 true
#define WIFI_NETWORK_TYPE WIFI_NETWORK_WIFI101
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
#define BOARD_TYPE "SAMD NANO_33_IOT"
#define WIFI_NETWORK_WIFININA true
#define WIFI_NETWORK_TYPE WIFI_NETWORK_WIFININA
#elif defined(ARDUINO_SAMD_MKRFox1200)
#define BOARD_TYPE "SAMD MKRFox1200"
#elif ( defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) )
#define BOARD_TYPE "SAMD MKRWAN13X0"
#elif defined(ARDUINO_SAMD_MKRGSM1400)
#define BOARD_TYPE "SAMD MKRGSM1400"
#elif defined(ARDUINO_SAMD_MKRNB1500)
#define BOARD_TYPE "SAMD MKRNB1500"
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
#define BOARD_TYPE "SAMD MKRVIDOR4000"
#elif defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS)
#define BOARD_TYPE "SAMD ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS"
#elif defined(ADAFRUIT_FEATHER_M0_EXPRESS)
#define BOARD_TYPE "SAMD21 ADAFRUIT_FEATHER_M0_EXPRESS"
#elif defined(ADAFRUIT_METRO_M0_EXPRESS)
#define BOARD_TYPE "SAMD21 ADAFRUIT_METRO_M0_EXPRESS"
#elif defined(ADAFRUIT_CIRCUITPLAYGROUND_M0)
#define BOARD_TYPE "SAMD21 ADAFRUIT_CIRCUITPLAYGROUND_M0"
#elif defined(ADAFRUIT_GEMMA_M0)
#define BOARD_TYPE "SAMD21 ADAFRUIT_GEMMA_M0"
#elif defined(ADAFRUIT_TRINKET_M0)
#define BOARD_TYPE "SAMD21 ADAFRUIT_TRINKET_M0"
#elif defined(ADAFRUIT_ITSYBITSY_M0)
#define BOARD_TYPE "SAMD21 ADAFRUIT_ITSYBITSY_M0"
#elif defined(ARDUINO_SAMD_HALLOWING_M0)
#define BOARD_TYPE "SAMD21 ARDUINO_SAMD_HALLOWING_M0"
#elif defined(ADAFRUIT_METRO_M4_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_METRO_M4_EXPRESS"
#elif defined(ADAFRUIT_GRAND_CENTRAL_M4)
#define BOARD_TYPE "SAMD51 ADAFRUIT_GRAND_CENTRAL_M4"
#elif defined(ADAFRUIT_FEATHER_M4_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_FEATHER_M4_EXPRESS"
#elif defined(ADAFRUIT_ITSYBITSY_M4_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_ITSYBITSY_M4_EXPRESS"
#elif defined(ADAFRUIT_TRELLIS_M4_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_TRELLIS_M4_EXPRESS"
#elif defined(ADAFRUIT_PYPORTAL)
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYPORTAL"
#elif defined(ADAFRUIT_PYPORTAL_M4_TITANO)
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYPORTAL_M4_TITANO"
#elif defined(ADAFRUIT_PYBADGE_M4_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYBADGE_M4_EXPRESS"
#elif defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE)
#define BOARD_TYPE "SAMD51 ADAFRUIT_METRO_M4_AIRLIFT_LITE"
#elif defined(ADAFRUIT_PYGAMER_M4_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYGAMER_M4_EXPRESS"
#elif defined(ADAFRUIT_PYGAMER_ADVANCE_M4_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYGAMER_ADVANCE_M4_EXPRESS"
#elif defined(ADAFRUIT_PYBADGE_AIRLIFT_M4)
#define BOARD_TYPE "SAMD51 ADAFRUIT_PYBADGE_AIRLIFT_M4"
#elif defined(ADAFRUIT_MONSTER_M4SK_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_MONSTER_M4SK_EXPRESS"
#elif defined(ADAFRUIT_HALLOWING_M4_EXPRESS)
#define BOARD_TYPE "SAMD51 ADAFRUIT_HALLOWING_M4_EXPRESS"
#elif defined(SEEED_WIO_TERMINAL)
#define BOARD_TYPE "SAMD SEEED_WIO_TERMINAL"
#elif defined(SEEED_FEMTO_M0)
#define BOARD_TYPE "SAMD SEEED_FEMTO_M0"
#elif defined(SEEED_XIAO_M0)
#define BOARD_TYPE "SAMD SEEED_XIAO_M0"
#elif defined(Wio_Lite_MG126)
#define BOARD_TYPE "SAMD SEEED Wio_Lite_MG126"
#elif defined(WIO_GPS_BOARD)
#define BOARD_TYPE "SAMD SEEED WIO_GPS_BOARD"
#elif defined(SEEEDUINO_ZERO)
#define BOARD_TYPE "SAMD SEEEDUINO_ZERO"
#elif defined(SEEEDUINO_LORAWAN)
#define BOARD_TYPE "SAMD SEEEDUINO_LORAWAN"
#elif defined(SEEED_GROVE_UI_WIRELESS)
#define BOARD_TYPE "SAMD SEEED_GROVE_UI_WIRELESS"
#elif defined(__SAMD21E18A__)
#define BOARD_TYPE "SAMD21E18A"
#elif defined(__SAMD21G18A__)
#define BOARD_TYPE "SAMD21G18A"
#elif defined(__SAMD51G19A__)
#define BOARD_TYPE "SAMD51G19A"
#elif defined(__SAMD51J19A__)
#define BOARD_TYPE "SAMD51J19A"
#elif defined(__SAMD51P19A__)
#define BOARD_TYPE "__SAMD51P19A__"
#elif defined(__SAMD51J20A__)
#define BOARD_TYPE "SAMD51J20A"
#elif defined(__SAM3X8E__)
#define BOARD_TYPE "SAM3X8E"
#elif defined(__CPU_ARC__)
#define BOARD_TYPE "CPU_ARC"
#elif defined(__SAMD51__)
#define BOARD_TYPE "SAMD51"
#else
#define BOARD_TYPE "SAMD Unknown"
#endif
#endif
#if ( defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \
defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || defined(NRF52840_CLUE) || \
defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) )
#if defined(WIFININA_USE_NRF52)
#undef WIFININA_USE_NRF52
#endif
#define WIFININA_USE_NRF52 true
#if defined(NRF52840_FEATHER)
#define BOARD_TYPE "NRF52840_FEATHER_EXPRESS"
#elif defined(NRF52832_FEATHER)
#define BOARD_TYPE "NRF52832_FEATHER"
#elif defined(NRF52840_FEATHER_SENSE)
#define BOARD_TYPE "NRF52840_FEATHER_SENSE"
#elif defined(NRF52840_ITSYBITSY)
#define BOARD_TYPE "NRF52840_ITSYBITSY_EXPRESS"
#elif defined(NRF52840_CIRCUITPLAY)
#define BOARD_TYPE "NRF52840_CIRCUIT_PLAYGROUND"
#elif defined(NRF52840_CLUE)
#define BOARD_TYPE "NRF52840_CLUE"
#elif defined(NRF52840_METRO)
#define BOARD_TYPE "NRF52840_METRO_EXPRESS"
#elif defined(NRF52840_PCA10056)
#define BOARD_TYPE "NORDIC_NRF52840DK"
#elif defined(NINA_B302_ublox)
#define BOARD_TYPE "NINA_B302_ublox"
#elif defined(NINA_B112_ublox)
#define BOARD_TYPE "NINA_B112_ublox"
#elif defined(PARTICLE_XENON)
#define BOARD_TYPE "PARTICLE_XENON"
#elif defined(MDBT50Q_RX)
#define BOARD_TYPE "RAYTAC_MDBT50Q_RX"
#elif defined(ARDUINO_NRF52_ADAFRUIT)
#define BOARD_TYPE "ARDUINO_NRF52_ADAFRUIT"
#else
#define BOARD_TYPE "nRF52 Unknown"
#endif
#endif
#if ( defined(ARDUINO_SAM_DUE) || defined(__SAM3X8E__) )
#if defined(WIFININA_USE_SAMDUE)
#undef WIFININA_USE_SAMDUE
#endif
#define WIFININA_USE_SAMDUE true
// For SAM DUE
#if defined(ARDUINO_SAM_DUE)
#define BOARD_TYPE "SAM DUE"
#elif defined(__SAM3X8E__)
#define BOARD_TYPE "SAM SAM3X8E"
#else
#define BOARD_TYPE "SAM Unknown"
#endif
#endif
#if ( defined(STM32F0) || defined(STM32F1) || defined(STM32F2) || defined(STM32F3) ||defined(STM32F4) || defined(STM32F7) || \
defined(STM32L0) || defined(STM32L1) || defined(STM32L4) || defined(STM32H7) ||defined(STM32G0) || defined(STM32G4) || \
defined(STM32WB) || defined(STM32MP1) ) && !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) )
#if defined(WIFININA_USE_STM32)
#undef WIFININA_USE_STM32
#endif
#define WIFININA_USE_STM32 true
#if defined(STM32F0)
#warning STM32F0 board selected
#define BOARD_TYPE "STM32F0"
#elif defined(STM32F1)
#warning STM32F1 board selected
#define BOARD_TYPE "STM32F1"
#elif defined(STM32F2)
#warning STM32F2 board selected
#define BOARD_TYPE "STM32F2"
#elif defined(STM32F3)
#warning STM32F3 board selected
#define BOARD_TYPE "STM32F3"
#elif defined(STM32F4)
#warning STM32F4 board selected
#define BOARD_TYPE "STM32F4"
#elif defined(STM32F7)
#warning STM32F7 board selected
#define BOARD_TYPE "STM32F7"
#elif defined(STM32L0)
#warning STM32L0 board selected
#define BOARD_TYPE "STM32L0"
#elif defined(STM32L1)
#warning STM32L1 board selected
#define BOARD_TYPE "STM32L1"
#elif defined(STM32L4)
#warning STM32L4 board selected
#define BOARD_TYPE "STM32L4"
#elif defined(STM32H7)
#warning STM32H7 board selected
#define BOARD_TYPE "STM32H7"
#elif defined(STM32G0)
#warning STM32G0 board selected
#define BOARD_TYPE "STM32G0"
#elif defined(STM32G4)
#warning STM32G4 board selected
#define BOARD_TYPE "STM32G4"
#elif defined(STM32WB)
#warning STM32WB board selected
#define BOARD_TYPE "STM32WB"
#elif defined(STM32MP1)
#warning STM32MP1 board selected
#define BOARD_TYPE "STM32MP1"
#else
#warning STM32 unknown board selected
#define BOARD_TYPE "STM32 Unknown"
#endif
#endif
#ifdef CORE_TEENSY
#if defined(WIFININA_USE_TEENSY)
#undef WIFININA_USE_TEENSY
#endif
#define WIFININA_USE_TEENSY true
#if defined(__IMXRT1062__)
// For Teensy 4.1/4.0
#define BOARD_TYPE "TEENSY 4.1/4.0"
#elif defined(__MK66FX1M0__)
#define BOARD_TYPE "Teensy 3.6"
#elif defined(__MK64FX512__)
#define BOARD_TYPE "Teensy 3.5"
#elif defined(__MKL26Z64__)
#define BOARD_TYPE "Teensy LC"
#elif defined(__MK20DX256__)
#define BOARD_TYPE "Teensy 3.2" // and Teensy 3.1 (obsolete)
#elif defined(__MK20DX128__)
#define BOARD_TYPE "Teensy 3.0"
#elif defined(__AVR_AT90USB1286__)
#error Teensy 2.0++ not supported yet
#elif defined(__AVR_ATmega32U4__)
#error Teensy 2.0 not supported yet
#else
// For Other Boards
#define BOARD_TYPE "Unknown Teensy Board"
#endif
#endif
#if ( defined(ARDUINO_ARCH_RP2040) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || defined(ARDUINO_GENERIC_RP2040) )
#if defined(WIFININA_USE_RP2040)
#undef WIFININA_USE_RP2040
#endif
#define WIFININA_USE_RP2040 true
// Default pin 5 (in Mbed) or 17 to SS/CS
#if defined(ARDUINO_ARCH_MBED)
// For RPI Pico using Arduino Mbed RP2040 core
// SCK: GPIO2, MOSI: GPIO3, MISO: GPIO4, SS/CS: GPIO5
#define USE_THIS_SS_PIN 5
#if defined(BOARD_NAME)
#undef BOARD_NAME
#endif
#if defined(ARDUINO_NANO_RP2040_CONNECT)
#define BOARD_TYPE "MBED NANO_RP2040_CONNECT"
#define WIFI_NETWORK_WIFININA true
#define WIFI_NETWORK_TYPE WIFI_NETWORK_WIFININA
#elif defined(ARDUINO_RASPBERRY_PI_PICO)
#define BOARD_TYPE "MBED RASPBERRY_PI_PICO"
#elif defined(ARDUINO_ADAFRUIT_FEATHER_RP2040)
#define BOARD_TYPE "MBED ADAFRUIT_FEATHER_RP2040"
#elif defined(ARDUINO_GENERIC_RP2040)
#define BOARD_TYPE "MBED GENERIC_RP2040"
#else
#define BOARD_TYPE "MBED Unknown RP2040"
#endif
#else
// For RPI Pico using E. Philhower RP2040 core
// SCK: GPIO18, MOSI: GPIO19, MISO: GPIO16, SS/CS: GPIO17
#define USE_THIS_SS_PIN 17
#endif
#define SS_PIN_DEFAULT USE_THIS_SS_PIN
// For RPI Pico
#warning Use RPI-Pico RP2040 architecture
#endif
#if ( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) )
#if defined(BOARD_NAME)
#undef BOARD_NAME
#endif
#if defined(CORE_CM7)
#warning Using Portenta H7 M7 core
#define BOARD_TYPE "PORTENTA_H7_M7"
#else
#warning Using Portenta H7 M4 core
#define BOARD_TYPE "PORTENTA_H7_M4"
#endif
#define WIFI_NETWORK_PORTENTA_H7 true
#define WIFI_NETWORK_TYPE WIFI_NETWORK_PORTENTA_H7
#elif (ESP32)
#define USE_WIFI_NINA false
// To use the default WiFi library here
#define USE_WIFI_CUSTOM false
#endif
#ifndef BOARD_NAME
#define BOARD_NAME BOARD_TYPE
#endif
#endif //defines_h
// Code generated by Arduino IoT Cloud, DO NOT EDIT.
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
//const char THING_ID[] = "26f93dbd-eb78-4e57-8764-71926746b99c";
const char SSID[] = "SSID"; // Network SSID (name)
const char PASS[] = "PASSWORD"; // Network password (use for WPA, or use as key for WEP)
void onBResetChange();
bool rai1;
bool rai2;
bool rai3;
bool rete4;
bool canale5;
bool italia1;
bool la7;
bool tv8;
bool nove;
bool tVon;
bool unknownch;
bool bReset=false;
CloudTime upTime;
CloudTime startDate;
float tRai1 = 0, tRai2 = 0, tRai3 = 0, tRete4 = 0, tCanale5 = 0, tItalia1 = 0, tLa7 = 0, tTv8 = 0, tNove = 0, tUnknown, tGlobal = 0;
void initProperties(){
ArduinoCloud.addProperty(tGlobal, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(rai1, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(rai2, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(rai3, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(rete4, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(canale5, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(italia1, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(la7, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tv8, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(nove, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(unknownch, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tVon, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tRai1, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tRai2, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tRai3, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tRete4, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tCanale5, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tItalia1, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tLa7, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tTv8, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tNove, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(tUnknown, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(upTime, READ, ON_CHANGE, NULL);
ArduinoCloud.addProperty(bReset, READWRITE, ON_CHANGE, onBResetChange);
ArduinoCloud.addProperty(startDate, READ, ON_CHANGE, NULL);
}
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);





Comments