All Collections
IoT Projects Tutorials
Control servo motors remotely using XinaBox xChip OC05 (PCA9685) and CW02 (ESP32), connected to ubidots over MQTT
Control servo motors remotely using XinaBox xChip OC05 (PCA9685) and CW02 (ESP32), connected to ubidots over MQTT

Control servo motors (up-to 8) using XinaBox xChip OC05 – Servo Driver (PCA9685 PWM Controller & BU33SD5 Regulator) and xChip CW02 (ESP32).

Isabel Lopez avatar
Written by Isabel Lopez
Updated over a week ago

The ESP-WROOM-32 (ESP32) Core and Wi-Fi, Bluetooth module (CW02) allows users to send data from XinaBox’s modular xChips to the cloud, and control the device according to the obtained data.

The xChip OC05 talks to CW02 using I2C protocol. OC05 has 8 PWM channels. OC05 uses PCA9685 PWM controller to control servo motors using Pulse Width Modulation. Servo motors are optionally powered through external battery which is then regulated using BU33SD5 regulator. Servo motors can also be used with OC05 without batteries. With CW02 attached to OC05, CW02 gets data and processes to set PWM to control position of servo motors.

By the end of this guide, you will able to control servo motors remotely using Ubidots and Xinabox xChips IP01, CW02 and OC05.

Requirements

Step-by-Step

  1. Hardware Setup

  2. Setting up the Arduino IDE

  3. Modify Ubidots ESP MQTT Library

  4. Create slider Widget

  5. Coding

  6. Compile and Upload the code

  7. Summary

1. Hardware Setup

Connect CW02, OC05 and IP01 together using the XC10 xBUS connectors. You may connect it as shown in the diagram below. Please see this guide on how to assemble xChips generally.

Then, connect your device and PC through the IP01’s USB.

2. Setting up the Arduino IDE

  1. Install these libraries/cores to Arduino: 

NOTE: If you are not familiar with how to install libraries, please refer to the link: Installing Arduino libraries

  1. With the ESP32 core installed, select the ESP32 device you are working with. In this case, we are working with a “CW02(ESP32 module)”. To select your board from the Arduino IDE, select Tools > Board “XinaBox CW02”.

3. Modify Ubidots ESP MQTT Library

Ubidots ESP MQTT Library is by default made for ESP8266. Few modification have to be made inside the UbidotsESPMQTT library to make it useable for ESP32.

Open UbidotsESPMQTT.h , from <sketchbook location>\libraries  with Notepad or Notepad++ (preferred):

Comment or remove #include <ESP8266WiFi.h> , and add these two lines:

#include <Arduino.h>
#include <WiFi.h>

Replace the following line:

#define SERVER "industrial.api.ubidots.com"

with:

#define SERVER "industrial.ubidots.com"

The final code may look like this:

4. Create slider Widget

1.  Login to your Ubidots account:

1. Create a new device. To create a new device, click the "+" icon in the top right corner of the Device's section of your account.  Then, assign “OC05” device name:

Once the device is created it will be appear listed in the device section:

3.  Enter to the device created and add a new raw variable by pressing the "+" icon. The variable ought to be called “degrees”: 

Once the variable is created you should have the following result: 

IMPORTANT NOTE: In order to be able to establish the communication, the Device & Variable label assigned in the platform should be the same assigned in the code. To learn more about Devices & Variable Labels, refer to the following article.

4.  Go to the dashboard ("Data > Dashboards") section to create a new control widget. To create a new control widget into the Dashboard click on the “+” icon in the top-right corner of the dashboard user interface. Then, select "Slider" as widget type and assign the device and variable previously created. 

Set minimum value to “0” and maximum to “180” degrees. Enter Step size to 1:

Once the widget is created, you should have the following result:

5. Coding

Including libraries:

#include "UbidotsESPMQTT.h"
#include <xOC05.h>
#include <xCore.h>

Enter your Wi-Fi credentials and Ubidots TOKEN where indicated:

#define TOKEN "" // Put here your Ubidots TOKEN
#define WIFINAME "" //Put here your WiFi SSID
#define WIFIPASS "" // Put here your Wifi Pass

Defining constants:

#define DEVICE "oc05" // Put here your Ubidots device label
#define VARIABLE "degrees" // Put here your Ubidots variable label
#define SERVO_MAX 450 //Servo Motor maximum PWM
#define SERVO_MIN 130 //Servo Motor minimum PWM
#define SERVO_CHANNEL 1 //Servo channel select between 1-8

IMPORTANT NOTE: Make sure that Device and Variable LABEL are respectively assigned.

Creating Variables and Objects:

Ubidots client(TOKEN,"esp32");
xOC05 OC05;

uint16_t value,prevValue;

Ubidots MQTT needs to be assigned a callback function to be called every-time change in variable is detected.

void callback(char* topic, byte* payload, unsigned int length) {
  //Message is printed on Serial Monitor, everytime change is detected

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");  

  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }

  value = atoi((char*)payload);
  memset(payload,'\0',sizeof(payload));

  //Map degrees to Servo Motor PWM range
  value= map(value,0,180,SERVO_MIN,SERVO_MAX);

  //Change motor position if value has changed
  if(prevValue!=value)
  {
   //Change Servo Motor Position
   OC05.setPWM(SERVO_CHANNEL,value);
   prevValue=value;
  }  
}

One time setup:

void setup() {

  //Serial.begin(115200); //Uncomment this line to enable Serial debugging
  //client.setDebug(true); //Pass a true or false bool value to activate //debug messages
  client.wifiConnection(WIFINAME, WIFIPASS); //Connect to the Access Point
  client.begin(callback); //Begin MQTT connection with “callback” function

  Wire.begin(); //Begin I2C communication
  OC05.begin(); //Begin OC05
  OC05.setPWMFreq(60); //Set PWM frequency to 60Hz

  //Initialize variables
  value=0;
  prevValue=0;
   }
  //Message is printed on Serial Monitor, everytime change is detected

  Serial.print("Message arrived [");

  Serial.print(topic);

  Serial.print("] ");  

  for (int i=0;i<length;i++) {

    Serial.print((char)payload[i]);

  }

 

  value = atoi((char*)payload);

  memset(payload,'\0',sizeof(payload));

 

 

  //Map degrees to Servo Motor PWM range

  value= map(value,0,180,SERVO_MIN,SERVO_MAX);

 

  //Change motor position if value has changed

  if(prevValue!=value)

  {

   //Change Servo Motor Position

   OC05.setPWM(SERVO_CHANNEL,value);

   prevValue=value;

  }  

}


Loop operation, keeps running and updating again and again:

void loop() {
  //Reconnect if not connected to the Ubidots MQTT

  if(!client.connected()){
      client.reconnect();
      //Subscribe to the DEVICE and VARIABLE previously set
      client.ubidotsSubscribe(DEVICE,VARIABLE);
  }
  client.loop();
}

 
The Complete Code, please read the comments:

#include "UbidotsESPMQTT.h"
#include <xOC05.h>
#include <xCore.h>

#define TOKEN "" // Put here your Ubidots TOKEN
#define WIFINAME "" //Put here your WiFi SSID
#define WIFIPASS "" // Put here your Wifi Pass

#define DEVICE  "oc05"  // Put here your Ubidots device label
#define VARIABLE  "degrees"  // Put here your Ubidots variable label
#define SERVO_MAX 450 //Servo Motor maximum PWM
#define SERVO_MIN 130 //Servo Motor minimum PWM
#define SERVO_CHANNEL 1 //Servo channel select between 1-8

Ubidots client(TOKEN,"esp32");
xOC05 OC05;
uint16_t value,prevValue;

void callback(char* topic, byte* payload, unsigned int length) {
  //Message is printed on Serial Monitor, everytime change is detected
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");  
  for (int i=0;i<length;i++) {
    Serial.print((char)payload[i]);
  }
  value = atoi((char*)payload);
  memset(payload,'\0',sizeof(payload));

  //Map degrees to Servo Motor PWM range
  value= map(value,0,180,SERVO_MIN,SERVO_MAX);

  //Change motor position if value has changed
  if(prevValue!=value)
  {
   //Change Servo Motor Position
   OC05.setPWM(SERVO_CHANNEL,value);
   prevValue=value;
  }  
}

 

void setup() {

  //Serial.begin(115200); //Uncomment this line to enable Serial debugging
  //client.setDebug(true); //Pass a true or false bool value to activate //debug messages
  client.wifiConnection(WIFINAME, WIFIPASS); //Connect to the Access Point
  client.begin(callback); //Begin MQTT connection with “callback” function

  Wire.begin(); //Begin I2C communication
  OC05.begin(); //Begin OC05
  OC05.setPWMFreq(60); //Set PWM frequency to 60Hz

  //Initialize variables
  value=0;
  prevValue=0;
}

void loop() {
  //Reconnect if not connected to the Ubidots MQTT
  if(!client.connected()){
      client.reconnect();
      //Subscribe to the DEVICE and VARIABLE previously set
      client.ubidotsSubscribe(DEVICE,VARIABLE);
  }
  client.loop();
}

6. Compile and Upload the code

You will now use Arduino IDE to Compile and then upload the code to the CW02, having made sure you have selected CW02 board, and connected on the correct USB port.

In the Ubidots Dashboard the OC05 can be controlled with the slider widget that was added. When you slide, servomotor rotates to that specific position.

7. Summary

In this tutorial, we have shown how to control servomotors using XinaBox xChips CW02/OC05/IP01 with Ubidots remotely from anywhere. With XinaBox and Ubidots you can now control doors and windows from anywhere to automate your home. The project is fairly simple, and may take upto 20-25 minutes.

Other readers have also found useful...

Did this answer your question?