Skip navigation
2015

4. AardEnergy – Metering Chips

In this Blog

So far I have chosen sensors without much consideration of how the Arduino will handle the data. The plan is to use a meter chip with the Uno and to directly convert the sensor voltages (after suitable scaling) with the Due.  In this blog I will evaluate a number of meter chips for use with the Uno…ADE7753, ADE7763, MCP3905, MCP3909.

See previous Blogs…

http://www.element14.com/community/groups/arduino/blog/2015/11/23/1-aardenergy-kick-off--a-new-project

 

http://www.element14.com/community/groups/arduino/blog/2015/11/26/2-aardenergy-set-up-uno-and-due

 

http://www.element14.com/community/groups/arduino/blog/2015/12/10/3-aardenergy-current-and-voltage-transformers

Metering Chips

ADE7753

This chip is made by Analog Devices as part of their Energy Metering IC family. They say:

Analog Devices’ ADE energy measurement ICs address the challenges of next-generation smart meter architectures and are ideal for measuring active energy (kWh), apparent energy (kVA), reactive energy (kVAR), rms, and power quality with the highest accuracy in single phase and polyphase revenue meters, industrial instruments, and energy monitoring applications. ADI’s ADE energy measurement ICs combine analog-to-digital converters with fixed-function digital signal processors to perform critical measurements, while providing unparalleled functionality and ease of use.

This is a summary of its capabilities:

Part

ADE7753

Function

Single Phase Meter

Measurements Available

Apparent Power, Irms, Total Active Power, Total Reactive Power, Vrms

Current Sense Type

Current Transformer, Rogowski Coil, Shunt    

MPU Interface

Energy Pulses, SPI …see below

Current Channel Input Range

±0.5V maximum.

Voltage Channel Input Range

±0.5V maximum

Active Energy Accuracy

0.1%    

Special Features

Low Power, Waveform Sampling        

VSupply min

4.75V  

VSupply max

5.25V  

Supply current

5 mA

Price 1off Farnell

£2.63

SPI Description:

 

ADE7763

 

Part

ADE7763

Function

Single Phase Meter

Measurements Available

Apparent Power, Irms, Total Active Power, Vrms

Current Sense Type

Current Transformer, Rogowski Coil, Shunt    

MPU Interface

Energy Pulses, SPI …see below

Active Energy Accuracy

0.1%    

Current Channel Input Range

±0.5V maximum.

Voltage Channel Input Range

±0.5V maximum

Special Features

Low Power, Waveform Sampling        

VSupply min

4.75V  

VSupply max

5.25V  

Supply current

5 mA

Price 1off Farnell

£1.69

SPI description:

 

 

MCP3905

 

Part

MCP3905

Function

Single Phase Meter

Measurements Available

Real Power

Current Sense Type

Current Transformer, Shunt  

MPU Interface

Power Pulses

Active Energy Accuracy

0.1%    

Current Channel Input Range

±0.47V maximum.

Voltage Channel Input Range

±0.66V maximum

Special Features

 

VSupply min

4.5V    

VSupply max

5.5V    

Supply current

2.7 mA

Farnell Price

£1.14

 

 

MCP3909

 

Part

MCP3909

Function

Single Phase Meter

Measurements Available

Real Power on pulse output, waveforms on SPI

Current Sense Type

Current Transformer, Shunt  

MPU Interface

Power Pulses, SPI

Active Energy Accuracy

0.1%    

Current Channel Input Range

±0.47V maximum.

Voltage Channel Input Range

±0.66V maximum

Special Features

 

VSupply min

4.5V    

VSupply max

5.5V    

Supply current

2.7 mA

Farnell Price

£1.47

SPI:

 

Making a Choice of Meter Chip

 

The list of chips above was based on 3 requirements:

  • Single phase monitor
  • SPI interface, power and energy data
  • Low cost

The MCP3905 does not have an SPI interface, so is ruled out. The pulse output of this chip could be counted on an Arduino input but that was not my target application.

The MCP3909 has an SPI interface but that data is the raw waveform, so the chip is acting as an external ADC which again is not what I wanted to do in my application. I want to use the internal Arduino ADC on the Due and for the Uno I want a meter chip that does all the calculations and presents power and energy data at the SPI port.

The ADE7753 has all the required features, the power and energy calculation are done on the chip and the results are presented as data to the SPI port. The same is true of the ADE7763 which is less expensive but has less features as it does not calculate the Reactive Power. I’m going to use the ADE7753 as I’m not concerned about the small extra cost £2.63 against £1.69 and the Reactive Power may be of interest. Both of these chips have to ability to interface with Current Transformers or Rogowski coils to measure current. I’m interesting in Rogowski coils so this is a feature I will use at some point.

Product page:

http://www.analog.com/en/products/analog-to-digital-converters/integrated-special-purpose-converters/single-phase-metering-ic/ade7753.html

 

 

Sensor Interface

 

Current Transformer CT

 

What are the essential parameters we know about?

  • The input to the ADE7753 is a differential programmable gain amplifier with a range of ±500mV relative to analogue ground.
  • Input impedance 390k
  • The output of the current transformer is ±1000mV.
  • The power rail available from the Arduino Uno is 5V.
  • The signal can be 50Hz or 60Hz with a measurement Bandwidth of 14kHz Anti-aliasing cut-off frequency needs to be 10kHz.

The description of the interface to the ADE7753 in the evaluation circuit is based in a meter with direct connection to the mains wiring and as such is unsuitable for this application. We are using isolated sources for the signals to make them safe to handle on an Arduino board. However there has to be an anti-aliasing filter on the input and the normal operating range has to be limited to ±500mV relative to analogue ground. Our CT has an output of 1000mV so we need a ½ attenuation as well as the filter. From the datasheet a simple RC filter with a corner frequency of 10kHz is recommended to remove any high frequency noise. The input impedance of the ADE7753 amplifiers is 390k so we can use a voltage divider of say 1k resistors and a suitable capacitor to give 10kHz low-pass bandwidth. The equivalent resistance of the divider will be 1k in parallel with 1k or 500R. The capacitor can be calculated from frequency=1/(2πRC) and we will use 33n as the closest available value. So that we do not degrade the 0.5% accuracy of the chip too much we will use 0.1% resistors, and a 5% capacitor will be good enough.

 

Voltage Transformer VTx

 

What are the essential parameters we know about?

  • The input to the ADE7753 is a differential programmable gain amplifier with a range of ±500mV relative to analogue ground.
  • Input impedance 390k
  • The output of the voltage transformer is  ±17.2V
  • The power rail available from the Arduino Uno is 5V.
  • The signal can be 50Hz or 60Hz with a measurement Bandwidth of 14kHz. Anti-aliasing cut-off frequency needs to be 10kHz.

Our VTx has an output of 17.2V so we need an attenuation to 0.5V as well as the anti-aliasing filter with a corner frequency of 10kHz. The input impedance of the ADE7753 amplifiers is 390k so we can use a voltage divider of around 1k resistors and a suitable capacitor to give 10kHz low-pass bandwidth. If we choose resistors to ultimately give the same capacitor value as for the current measurement channel, we will only have to buy one type of capacitor. This is a good design aim as capacitors are available in fewer types and values compared to resistors. If we choose 510R as the lower value then the voltage divider is made with 17.4k and 510R resistors, which is an attenuation factor of 0.0284757, so 17.2V will be represented by 489.8mV which is within the measurement range of the ADE7753. The equivalent resistance of the divider is 17.4k in parallel with 510R or 495.5R and the capacitor can be calculated from frequency=1/(2πRC) and we will use 33n as the closest available value.

SPI Interface (Hardware)

 

This is the Arduino SPI reference page:

https://www.arduino.cc/en/Reference/SPI

…and the Atmel data sheet:

http://www.atmel.com/Images/doc8161.pdf

 

The Arduino Uno will be set up as the SPI master and the ADE7753 as the slave/peripheral. The logic signals can be directly connected, both operate on 5V logic:

SS Arduino is slave select, connect to ADE7753 nCS.

MISO Arduino is the data input from the Slave, connect to DOUT of the ADE7753.

MOSI Arduino is the Master Data Output to the slave, connect to DIN of the ADE7753.

SCK Arduino is the master clock output, connect to SCLK on the ADE7753, 10MHz spec.

The ADE7753 use mode2 transfers of data with the MSB leading.

 

Next Steps

Next we will design the circuit to be built onto the Uno prototype based on the details worked out in this Blog.

We will need to purchase the following parts:

Farnell Order Code 2313624 Manufacturer Part No  ADE7753ARSZADE7753ARSZ Meter Chip

Farnell Order Code 1670224 Manufacturer Part No  ERA6AEB511VERA6AEB511V 510R 125 mW 0.1 100 V

Farnell Order Code 2094720 Manufacturer Part No  ERA6ARB1742VERA6ARB1742V 17.4k 125 mW 0.1 100 V

Farnell Order Code: 2320843 Manufacturer Part No MC0805B333J500CT  0.033µ, ±5%, X7R, 50 V

Farnell Order Code 1426164 Manufacturer Part No  RE931-03RE931-03 ADAPTOR SMD SSOP-20


Hello,

 

Today I would like to share with you my second little project. Its an Arduino temperature logger which saves data on micro SD card and thanks to a short Python script it can also send data to Ubidots IOT application. The circuit itself is very simple, in order to complete it all you need is:

 

11 - jumper wires

1 - 4.7K ohm resistor

1 - DS18B20 temperature sensor

1 - SD card reader

1 - Arduino UNO

 

Here's the circuit's schematic:

 

Arduino SD card temperature logger

Here's a video showing how assemble the circuit:

 

Arduino sketch for this project:

#include <OneWire.h> //library for communication with temperature sensor
#include <DallasTemperature.h> //temperature sensor library
#include <SD.h> //sd card reader library available in every Arduino IDE
#include <SPI.h> //library for communication with SD card reader

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

File logs;  // variable responsible for writing to file 
float temp; //variable storing the current temperature
int number = 0; //variable holding the number indicating current entry in csv file

unsigned int hour = 20; //variable storing current hour
unsigned int minute = 45; //variable storing current minute 
unsigned int day = 2; //variable storing current day of the week
unsigned int date = 15; //variable storing current day of the month 
unsigned int month = 12; //variable storing current month
unsigned int year =  2015; //variable storing current year

unsigned int leap_year = 0; //variable for checking whether it's a leap year or not

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  SD.begin(10);
  // Start up the library
  sensors.begin();
} //end of void setup

void loop(void)
{ 
  //checking whether it's leap year or not
  if (year % 4 == 0)
  leap_year = 1;
  else
  leap_year = 0;
  
  
  //changing minutes
  if (minute < 55)
  minute +=5;
  else
  minute = 0;
  
  //changing hour
  if ((minute == 0) && (hour < 24))
  hour++;
  if ((minute == 0) && (hour == 24))
  hour = 0;
  
  //changing day of the week
  if((minute == 0) && (hour == 0) && (day <8))
  day +=1;
  if((minute == 0) && (hour == 0) && (day == 8))
  day = 1;
  
  //changing day of the month  
  //formula for 30 day months
  if ((date < 31) && ( (month == 4) || (month == 6) || (month == 9) || (month == 11)) && (hour == 0) && (minute ==0))
  {
   date++; 
  }
  if ((date == 31) && ( (month == 4) || (month == 6) || (month == 9) || (month == 11)) && (hour == 0) && (minute ==0))
  {
   date = 0;
   month++; 
  }
  
  //formula for February 
  if ( ((date < 29) && (month == 2) && (hour == 0) && (minute == 0) && (leap_year == 0)) || ((date < 30) && (month == 2) && (hour == 0) && (minute == 0) && (leap_year == 1)) )
  {
   date = date +1; 
  }
  if ( (date == 29) && (month == 2) && (hour == 0) && (minute == 0) && (leap_year == 0) || ((date == 30) && (month == 2) && (hour == 0) && (minute == 0) && (leap_year == 1)) )
  {
   date = 0;
   month = 3;
  }
  
  //formula for 31 day months
  if ((date < 32) && ( (month == 1) || (month == 3) || (month ==5) || (month == 7) || (month == 8) || (month == 10) || (month == 12)) && (hour == 0) && (minute ==0))
  {
    date++;
  }
  if ((date == 32) && ( (month == 1) || (month == 3) || (month ==5) || (month == 7) || (month == 8) || (month == 10) || (month == 12)) && (hour == 0) && (minute ==0))
  {
   date = 1;
   if(month <12)
   month++; 
   else
   month = 1;
  }
  
  
  //changing year
  if( (hour == 0) && (minute == 0) && (date == 1) && (month == 1))
  year++;
  
  
  sensors.requestTemperatures(); // Send the command to get temperatures
  temp =  sensors.getTempCByIndex(0); //assigning sensor's vale to the variable
  Serial.println(temp);
  
  
  logs = SD.open("logs.csv", FILE_WRITE); //assigning file to which we want to write the data
  if(logs) //if opening of the file was successful
  {
    
   if (number == 0)
   logs.println("sep=,"); //we add this line to the file so that excel 2013 and newer software knows that this is coma separated file
   
   //then we write entry number, date and sensor read
   logs.print(number);
   logs.print(",");
   
   logs.print(temp); //finally we add temperature read from sensor
   logs.print(",");
   
   if (hour < 10)
   logs.print("0"); //we add 0 is hour is lower than 10
   logs.print(hour);
   logs.print(":");
   if(minute <10) 
   logs.print("0"); //we add 0 if minute is lower than 10
   logs.print(minute);
   logs.print(" ");
   
   switch(day) //we add day of the week appropriately
   {
    case 1:
     logs.print("Monday");
     break;
    case 2:
     logs.print("Tuesday");
     break;
    case 3:
     logs.print("Wednesday");
     break;
    case 4:
     logs.print("Thursday");
     break;
    case 5:
     logs.print("Friday");
     break;
    case 6:
     logs.print("Saturday");
     break;
    case 7:
     logs.print("Sunday");
     break;
   }
   logs.print(" ");
   logs.print(date);
   logs.print(" ");
   
   switch(month)
   {
    case 1:
     logs.print("January");
     break;
    case 2:
     logs.print("February");
     break;
    case 3:
     logs.print("March");
     break;
    case 4:
     logs.print("April");
     break;
    case 5:
     logs.print("May");
     break;
    case 6:
     logs.print("June");
     break;
    case 7:
     logs.print("July");
     break;
    case 8:
     logs.print("August");
     break;
    case 9:
     logs.print("September");
     break;
    case 10:
     logs.print("October");
     break;
    case 11:
     logs.print("November");
     break;
    case 12:
     logs.print("December");
     break;
   }
   
   logs.print(" ");
   logs.println(year); //printing year to the file
   Serial.println("Saving successful");
   logs.close();//we close and save the file
  }
  logs.flush();
  
  
  delay(300000); // we delay program for 5 minutes and then take another read
  //delay(60000); //for testing purposes 1 minute
  //delay(2000);//for testing purposes 2 seconds
  number = number + 1; // we add 1 to the entry counter
}

 

Python script which allows communication between Arduino and Ubidots application:

from ubidots import ApiClient #importing ubidots api
from time import * #importing standard time library
import serial #importing pyserial library

api = ApiClient ('your_account_key') #key of our ubidots account
ser = serial.Serial('COM6', 9600, timeout = 0) #establishing communication with Arduino serial port

temp_val = api.get_variable('your_variable_key') #ubidots variable's key with which we want to communicate


while True:
    current_temp = ser.readline(6) #reading first 6 characters from serial port
    if ( (current_temp[:1] == '-')or(current_temp[:1] == '1') or (current_temp[:1] == '2') or (current_temp[:1] == '3') or (current_temp[:1] == '4') or (current_temp[:1] == '5') or (current_temp[:1] == '6') or (current_temp[:1] == '7') or (current_temp[:1] == '8') or (current_temp[:1] == '9') ):
            
            float_current_temp = float(current_temp[:5]) #converting value read from the serial port a float
            new_value = temp_temp.save_value({'value':float_current_temp}) #sending value to ubidots
            print ("sending successful")

 

Video explaining Arduino sketch and Python script, as well as providing introduction to Ubidots:

 

Please comment. Any feedback is very valuable for me, especially constructive criticism. If you like what I'm doing you can subscribe my channel on YouTube (https://www.youtube.com/user/W0j45), follow me on Twitter (https://twitter.com/milczarekw) and Instagram (https://www.instagram.com/milczarekw/).

 

Thank you for reading!

03 AardEnergy – Current and Voltage Transformers

 

In this Blog

I have a Current Transformer and a Voltage Transformer to evaluate. In this blog there will be a description of the sensors and some analysis of the signals as well as some measurements to assess performance.

 

See previous Blogs…

http://www.element14.com/community/groups/arduino/blog/2015/11/23/1-aardenergy-kick-off--a-new-project

http://www.element14.com/community/groups/arduino/blog/2015/11/26/2-aardenergy-set-up-uno-and-due

Current Transformer

The current transformer (CT) was bought from Amazon; the SCT 013-030 is a 30A device that costs £8.75.

http://www.amazon.co.uk/gp/product/B005CTWE8A?psc=1&redirect=true&ref_=oh_aui_detailpage_o01_s00

This part is made by YHDC and details can be found on their website:

http://www.yhdc.com/en/product/320/

The part supplied is fitted with an internal resistor that converts the output of the current transformer (CT) to a voltage with the scaling of ±30A input to ±1V output.

Check that the part supplied has the resistor before use. You can do this with by measuring the output resistance with a meter, it should read about 37R. It is clearly marked 30A/1V. You should note that a CT without a resistor will generate very high voltage – see the article linked below in the section on Transformers.

 

This CT has insulation rated for 1000VAC and we will only be using it clipped onto wire that is also insulated. It must be applied to a single live or neutral wire and our project will be limited to use with the meter connection on the supply to our house, like this:

Note that if you place the CT over an appliance cable that has live and neutral running through it, the magnetic fields cancel and the CT will read zero.

The electrical supply to my house is 15kW so in theory I could draw 65Arms through the meter and my 30A sensor would not be able to detect anything above 30A. Also we need to be mindful that the peak current of my sensor is 30A so the maximum rms current will be 21.2Arms. 65Arms requires 92A peak measurement. For my house this should be okay as we do not use electrical power for cooking or heating water. We have oil filled radiators but these are used on rare occasions. The peak consumption will come from the washing machine and the tumble drier. I am expecting my 30A sensor to be able to deal with these loads. However if you expect your loads to be higher you need to purchase a suitably rated sensor. For example if you want the full current capability of 65Arms the peak current will be 92A so you should buy a 100A sensor. There is a 100A/1V sensor in the YHDC product range and you should buy that.

It is a difficult choice to design a measurement system either for the maximum possible or the maximum you normally need. If I use a 100A sensor but normally I am measuring around 1Arms with occasional 20Arms maximum then I am using the sensor at the bottom of its range and suffer the inaccuracy that entails. However if my supply is normally around 1A but with 60Arms occasional consumption I have to use a 100A peak sensor and put up with inaccuracy at 1Arms.

Note that the jack plug is compatible with this cable mounted socket from Farnell 1280665

http://uk.farnell.com/webapp/wcs/stores/servlet/ProductDisplay?catalogId=15001&langId=44&urlRequestType=Base&partNumber=1280665&storeId=10151

Voltage Transformer

The voltage transformer (VTx) was bought from Farnell 2112026:

http://uk.farnell.com/ideal-power/77db-06-09/adaptor-uk-9v-0-67a/dp/2112026?ost=2112026&selectedCategoryId=&categoryName=All+Categories&categoryNameResp=All+Categories

Follow the link to find the datasheet.

 

The transformer will operate at no load and the datasheet specifies the output as 11.6Vac ±3% with a nominal input of 240Vac. The output is specified as rms so the peak output will be nominally ±16.4V. However we should note that the electrical system in the UK has a nominal rating of 230Vac and a maximum of 10% which means 252Vac and ±358V peak. So the maximum output of the VTx will be ±17.2V

To measure the mains voltage, the VTx will be plugged into the ring main. To get the most accurate reading, choose a wall socket close to the meter to minimise voltage drops around the ring.

 

Note that the jack plug is compatible with this socket from Farnell 3648102

http://uk.farnell.com/webapp/wcs/stores/servlet/ProductDisplay?catalogId=15001&langId=44&urlRequestType=Base&partNumber=3648102&storeId=10151

Some Test Results

The following tests we done under workshop conditions rather than home conditions. The CT and the VTx were compared with a precision current and voltage amplifier using a National Instruments NI USB 6008 DAQ logger with Signal Express. The load and the VTx were plugged into an extension cable and the CT was installed into the case that housed the instrumentation amplifiers.

Current Transformer Results

Direct measurement 7.83A

CT Measurement 257.29mV

Scaling 7.83/257.29 = 0.0304A/mV

Voltage Transformer Results

Direct measurement 236.38

Tx Measurement 11.346

Scaling 236.38/11.346 = 20.8V/V

Current Transformer Basics

This is a useful explanation about current transformers:

http://www.electronics-tutorials.ws/transformer/current-transformer.html

Next Steps

So far I have chosen sensors without much consideration of how the Arduino will handle the data. The plan is to use a meter chip with the Uno and to directly convert the sensor voltages (after suitable scaling) with the Due.  In the next blog I will evaluate a number of meter chips for use with the Uno…ADE7753, ADE7763, CS5463, MCP3905, MCP3909.

Hello guys,

 

I've created a video tutorial about saving and sending Arduino logs via email and Twitter by using Python script and wanted to share it with you. You don't have to know Python to do it, all that is required is changing few variables so that the script can communicate with your email and Twitter accounts. The video includes installation of required software, as well as short code summary. Here's the video:

 

In this post I am going to show how to use an Arduino board and BitVoicer Server to control a few LEDs with voice commands. I will be using the Arduino Micro in this post, but you can use any Arduino board you have at hand.

 

BVS Demo Image 1

 

 

The following procedures will be executed to transform voice commands into LED activity:

 

  1. Audio waves will be captured and amplified by the Sparkfun Electret Breakout board;
  2. The amplified signal will be digitalized and buffered in the Arduino using its analog-to-digital converter (ADC);
  3. The audio samples will be streamed to BitVoicer Server using the Arduino serial port;
  4. BitVoicer Server will process the audio stream and recognize the speech it contains;
  5. The recognized speech will be mapped to predefined commands that will be sent back to the Arduino;
  6. The Arduino will identify the commands and perform the appropriate action.

 

The video above shows the final result of this post. Note in the video that BitVoicer Server also provides synthesized speech feedback. This speech feedback is defined in the server and reproduced by the server audio adapter, but the synthesized audio could also be sent to the Arduino and reproduced using a digital-to-analog converter (DAC). In my next post, I am going to show how to use the Arduino DUE, one amplified and one speaker to reproduce the synthesized speech using the Arduino itself.


List of Materials:



STEP 1: Wiring


The first step is to wire the Arduino and the breadboard with the components as shown in the pictures below.


FritzingProtoboard.jpg


Img2.jpg


Img3.jpg


Img4.jpg

 

The most important detail here refers to the analog reference provided to the Arduino ADC. In my tests, I got better results using 3.3V with the Sparkfun Electrect Breakout. That is why I added a jumper between the 3.3V pin and the AREF pin. If you decide to use the analogRead funcion (for any reason) while 3.3V is being applied to the AREF pin, you MUST call analogReference(EXTERNAL) before you use the analogRead function. Otherwise, you will short together the active reference voltage (internally generated) and the AREF pin, possibly damaging the microcontroller on your Arduino board.


STEP 2: Uploading the code to the Arduino


Now you have to upload the code below to your Arduino. You can also download the Arduino sketch from the link below. Before you upload the code, you must properly install the BitVoicer Server libraries into the Arduino IDE (Importing a .zip Library).


Sketch: BVS_Demo1.ino


#include <BVSP.h>
#include <BVSMic.h>


// Defines the Arduino pin that will be used to capture audio
#define BVSM_AUDIO_INPUT 5


// Defines the LED pins
#define RED_LED_PIN 6
#define YELLOW_LED_PIN 9
#define GREEN_LED_PIN 10


// Defines the constants that will be passed as parameters to
// the BVSP.begin function
const unsigned long STATUS_REQUEST_TIMEOUT = 1000;
const unsigned long STATUS_REQUEST_INTERVAL = 2000;


// Defines the size of the audio buffer
const int AUDIO_BUFFER_SIZE = 64;


// Defines the size of the receive buffer
const int RECEIVE_BUFFER_SIZE = 2;


// Initializes a new global instance of the BVSP class
BVSP bvsp = BVSP();


// Initializes a new global instance of the BVSMic class
BVSMic bvsm = BVSMic();


// Creates a buffer that will be used to read recorded samples
// from the BVSMic class
byte audioBuffer[AUDIO_BUFFER_SIZE];


// Creates a buffer that will be used to read the commands sent
// from BitVoicer Server.
// Byte 0 = pin number
// Byte 1 = pin value
byte receiveBuffer[RECEIVE_BUFFER_SIZE];


void setup()
{
  // Sets up the pin modes
  pinMode(RED_LED_PIN, OUTPUT);
  pinMode(YELLOW_LED_PIN, OUTPUT);
  pinMode(GREEN_LED_PIN, OUTPUT);

  // Starts serial communication at 115200 bps
  Serial.begin(115200);

  // Sets the Arduino serial port that will be used for
  // communication, how long it will take before a status request
  // times out and how often status requests should be sent to
  // BitVoicer Server.
  bvsp.begin(Serial, STATUS_REQUEST_TIMEOUT, STATUS_REQUEST_INTERVAL);

  // Defines the function that will handle the frameReceived
  // event
  bvsp.frameReceived = BVSP_frameReceived;

  // Prepares the BVSMic class timer
  bvsm.begin();
}


void loop()
{
  // Checks if the status request interval has elapsed and if it
  // has, sends a status request to BitVoicer Server
  bvsp.keepAlive();

  // Checks if there is data available at the serial port buffer
  // and processes its content according to the specifications
  // of the BitVoicer Server Protocol
  bvsp.receive();


  // Checks if there is one SRE available. If there is one,
  // starts recording.
  if (bvsp.isSREAvailable())
  {
    // If the BVSMic class is not recording, sets up the audio
    // input and starts recording
    if (!bvsm.isRecording)
    {
      bvsm.setAudioInput(BVSM_AUDIO_INPUT, EXTERNAL);
      bvsm.startRecording();
    }


    // Checks if the BVSMic class has available samples
    if (bvsm.available)
    {
      // Makes sure the inbound mode is STREAM_MODE before
      // transmitting the stream
      if (bvsp.inboundMode == FRAMED_MODE)
        bvsp.setInboundMode(STREAM_MODE);
  
      // Reads the audio samples from the BVSMic class
      int bytesRead = bvsm.read(audioBuffer, AUDIO_BUFFER_SIZE);

      // Sends the audio stream to BitVoicer Server
      bvsp.sendStream(audioBuffer, bytesRead);
    }
  }
  else
  {
    // No SRE is available. If the BVSMic class is recording,
    // stops it.
    if (bvsm.isRecording)
      bvsm.stopRecording();
  }
}


// Handles the frameReceived event
void BVSP_frameReceived(byte dataType, int payloadSize)
{
  // Checks if the received frame contains binary data
  // 0x07 = Binary data (byte array)
  if (dataType == DATA_TYPE_BINARY)
  {
    // If 2 bytes were received, process the command.
    if (bvsp.getReceivedBytes(receiveBuffer, RECEIVE_BUFFER_SIZE) ==
      RECEIVE_BUFFER_SIZE)
    {
      analogWrite(receiveBuffer[0], receiveBuffer[1]);
    }
  }
}





This sketch has four major parts:


  • Library references and variable declaration: The first two lines include references to the BVSP and BVSMic libraries. These libraries are provided by BitSophia and can be found in the BitVoicer Server installation folder. The other lines declare constants and variables used throughout the sketch. The BVSP class is used to communicate with BitVoicer Server and the BVSMic class is used to capture and store audio samples.
  • Setup function: This function initializes serial communication, the BVSP class, the BVSMic class and sets the “event handler” (it is actually a function pointer) for the frameReceived event.
  • Loop function: This function performs three important actions: requests status info to the server (keepAlive() function), checks if the server has sent any data and processes the received data (receive() function), and controls the recording and sending of audio streams (isSREAvailable(), startRecording(), stopRecording() and sendStream() functions).
  • BVSP_frameReceived function: This function is called every time the receive() function identifies that one complete frame has been received. Here I run the command sent from BitVoicer Server. The command contains 2 bytes. The first byte indicates the pin and the second byte indicates the pin value. I use the analogWrite() function to set the appropriate value to the pin.

 

STEP 3: Importing BitVoicer Server Solution Objects

 

Now you have to set up BitVoicer Server to work with the Arduino. BitVoicer Server has four major solution objects: Locations, Devices, BinaryData and Voice Schemas.

 

Locations represent the physical location where a device is installed. In my case, I created a location called Home.


Devices are the BitVoicer Server clients. I created a Mixed device, named it ArduinoMicro and entered the communication settings. NOTE ABOUT ARDUINO MICRO: it uses RTS and DTR so you have to enable these settings in the communication tab. I also created a SystemSpeaker device to synthesize speech using the server audio adapter.


BinaryData is a type of command BitVoicer Server can send to client devices. They are actually byte arrays you can link to commands. When BitVoicer Server recognizes speech related to that command, it sends the byte array to the target device. I created one BinaryData object to each pin value and named them ArduinoMicroGreenLedOn, ArduinoMicroGreenLedOff and so on. I ended up with 18 BinaryData objects in my solution, so I suggest you download and import the objects from the VoiceSchema.sof file below.


Voice Schemas are where everything comes together. They define what sentences should be recognized and what commands to run. For each sentence, you can define as many commands as you need and the order they will be executed. You can also define delays between commands. That is how I managed to perform the sequence of actions you see in the video.


You can import (Importing Solution Objects) all solution objects I used in this post from the files below. One contains the Devices and the other contains the Voice Schema and its Commands.


Files:



STEP 4: Conclusion


That is it! I hope you liked it.


You have everything you need to run the demo shown in the video. Note that in the video I started by enabling the ArduinoMicro device in the BitVoicer Server Manager. As soon as it gets enabled, the Arduino identifies an available Speech Recognition Engine and starts streaming audio to BitVoicer Server.


You can follow the recognition results in the Server Monitor tool available in the BitVoicer Server Manager.


In my next post I will show how you can reproduce synthesized speech using an Arduino DUE.




Hello everyone,

 

I'm new here so I'm going to introduce myself. I'm Wojtek and I come from Poland, currently I''m 25 y.o. and I'm just starting my journey with Arduino. In the future I would like to share with you my projects and I hope you can provide some insight and constructive criticism.

 

Ok, so now lets hop into the project itself. It's rather basic because for now I don't have that many parts (just Arduino board, diodes, some resistors, tact switches and photoresistors). The chain uses photoresistor to read the brightness outside (that is why I recommend sticking it to the window or keeping it on the wall outside of it). Direct exposure to sunlight returns a value of ~15 - 25, during overcast day the value rises to 60 and when it gets relatively dark the returned value is ~650. That's why I decided to turn the chain on when the value is higher than 650.

 

You can see bare construction in the video below:

 

That's how it looks in the bowl with Christmas glass balls:

 

Parts required to assemble the chain:

 

1 - Arduino UNO

6 -  LED diodes

1 - photoresistor

6 - 280 ohm resistors (for diodes)

1 - 1K ohm resistor (for photoresistor)

Bunch of cables

 

You can find source code here: https://t.co/7fGqjvEFEq

Schematics are available here: Arduino based Christmas LED chain - Imgur

 

If you like what I'm doing you can follow me on Twitter https://twitter.com/milczarekw and subscribe on YouTube https://www.youtube.com/user/W0j45

 

I really appreciate your attention and I hope you've liked my entry.

 

 

UPDATE!!!

I've added potentiometer and a button to the circuit. Thanks to the potentiometer you can control brightness of the LEDs (they are connected through PWMs so they can act as analog pins), whereas the button controls which program is being used. Previously there was an infinite loop of three programs.

 

Here's a video presenting the new version:

 

Schematics for the upgraded version: https://t.co/D2thcn5300

Source code: https://t.co/ikjVfC38FE

Few months ago we needed to realise an interactive experiment for kids, consisting in making light pass through a prism to be dispersed into a rainbow. The light was powered by a 220 V power outlet and must be controlled by kids looking at the experiment. Needless to say, the simplest solution was just to mount a switch on the power cord, such that the visitors can just switch the light on and off. In order for the experiment to be ready for next visitor, a better solution was evaluated to be a push button. But having a push button (or a switch) directly connected to 220 V can be potentially dangerous. Even if there are clever devices or mounting strategies to reduce such a risk to zero, we soon turned to a different solution, for the sake of originality.

 

We just connected an ultrasonic sensor and a relay to an Arduino UNO board. An ultrasonic sensor is a device composed of an ultrasonic source and an ultrasonic detector mounted on a PCB in such a way that both point in the same direction. Both the source and the detector are usually made of piezoelectric devices: piezoelectricity is a physical phenomenon consisting in the production of a tiny electrical current by a crystal when compressed or, conversely, in the change of the size of those crystals when an electrical current flows through them. A source of ultrasonic waves can be obtained connecting a small piezoelectric crystal to an oscillating current: the crystal oscillates with the same frequency and oscillations produce feeble sound waves. If the frequency is higher than 20 kHz they cannot be perceived by human ears and sound waves whose frequency is higher than that are said to be ultrasonic.

 

In devices such as the HC-SR04, ultrasonic sound waves are produced such that they travel in a cone of about 20 degrees aperture around a direction parallel to the axis of the emitter.

 

As all the waves, sound waves impinging against an obstacle, are reflected. When reflected back by an obstacle placed in front of the emitter, the waves travel back toward it and reach the sensor mounted sideways to the source. The detector is a crystal similar to that of the emitter: when sound waves reach it, it starts vibrating with the same frequency of the waves and produces a small oscillating current that can be amplified and measured by an electronic circuit.

 

When the HC-SR04 detects a positive signal with at least 10 microseconds duration on one of its pins (the trigger pin), it triggers the emitter to produce a burst of 40 kHz ultrasonic waves. When the waves are reflected back and detected, the circuit emits a pulse on another pin (the echo pin) whose duration is proportional to the time elapsed from the end of the trigger pulse to the start of the echo pulse.

 

Using this device is then extremely simple with Arduino: just connect the GND and 5V pins to the corresponding pins on Arduino, while the trigger and echo pins must be connected to digital Arduino pins (e.g. 9 and 10). The pin connected to the trigger pin of the HC-SR04 must be configured as an output pin, since Arduino must be able to raise the voltage on it from zero to 5 V, while the echo pin should be configured as an input pin, since Arduino must detect when it flips from 0 to 5 V.

 

That is done in the setup() method as

#define trigPin 9
#define echoPin 10

void setup() {
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
}

 

In order to send a trigger to the device, one need a 5 V pulse on pin 9 whose duration is at least 10 microseconds. This can be done writing a method such as the following:

 

void trig() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
}

 

The first instruction puts the pin to ground for at least two microseconds, then it raises it to 5 V, where it stays for 10 microseconds, when it goes back to zero. Once triggered the device emits the burst of ultrasonic waves and, when the device detects the echo of such a signal, it provides a positive signal on the echo pin whose duration is proportional to the time elapsed since the emission of the sound. The length of such a signal can be measured with the puseIn() Arduino function. When called, this function waits for a change in a pin status and returns the pulse duration, i.e. the time the pin stays in the new state.

 

The loop() method then reads

 

void loop() {
    trig();
    int duration = pulseIn(echoPin, HIGH);
    ...
}

 

The trig() method repeatedly trigger the device, while the pulseIn() function waits until the echo pin turns from LOW to HIGH, returning the duration of such a state.The duration of the echo pulse is proportional to the time elapsed from trigger to echo, i.e. to the time for an ultrasonic pulse to reach an obstacle and come back. It is, in other words, twice the time needed for the waves to reach the obstacle that, in turn, depends on the distance of the obstacle and the speed of the waves, that is the speed of sound v equal to about 330 m/s. As a result, one can estimate the distance d of any obstacle as d=v/, t being half the time measured with Arduino.

 

If such a distance is below a certain threshold one can operate a relays: we define a global variable called status representing the status of the relay. Then, the loop() method is as follows:

 

void loop() {
    trig(i);
    int duration = pulseIn(echoPin, HIGH);
    if ((duration < THRESHOLD) && (status[ == LOW)) {
      push();  
    } else if ((duration >= THRESHOLD) && (status == HIGH)) {
      releas();
    }
  }
}

 

THRESHOLD is a constant representing the minimum time a sound wave should take to go back and forth from the obstacle. It is not necessary to find its exact value. It can be determined experimentally just finding the number returned by the sensor when the obstacle is at the wanted distance.

 

The push() and releas() methods are intended to switch on and off the device opening and closing the relay. Note that the name of the second function is releas() and not release(), the latter being a system function. They act as functions who virtually simulate pushing and releasing a button. Pushing the button is achieved with

 

void push() {
  if ((millis() - lastActivation) > TIMEOUT) {
    status = HIGH;
    digitalWrite(relayPin, HIGH);
    lastActivation = millis();
  }
}

 

In principle one just need to put the relay pin to HIGH with digitalWrite(relayPin, HIGH. In this case when you approach the distance at which the switch closes, small fluctuations of the measurements cause the relay to continuously flip between the two states. With the code above, before switching the load on, we compare the return value of the millis() function with a gloabl unsigned long variable called lastActivation. millis() returns the number of milliseconds elapsed since the beginning of the execution of the sketch and is then a way to measure time. lastActivation stores the time at which the relay changed status last time (see the last line in the while loop). Only if the time elapsed between the last operation on the relay and the current time is greater than a given timeout, the relay can be newly operated. In our case we used a timeout of 1 s (i.e. TIMEOUT = 1000) in such a way that, once switched on the lamp stay on for at least 1 s before going off and viceversa.

 

The releas() function works exactly the same way, but it puts the relay pin to LOW opening the circuit.

 

DSC_1180.JPG

In the picture above you can see the system and how it operates (the real system we built had two sensors and two relays, each dedicated to a different device. The Arduino board can be seen in the middle. On its right there is the ultrasonic sensor. Relays can be seen on top of the figure. The sensors and the relays were covered by a transparent plexiglass screen with two holes corresponding to the position of the sensor (there is no need for the screen to be transparent: we chose it to be as such to let the users see what was inside). The holes were necessary to let the sound waves to be propagated toward the ceiling (the plexiglass screen reflects sound waves). Putting a hand close to the hole through which the sound waves pass, makes such waves to be reflected: the time needed to travel back and forth is recognised to be short enough and the corresponding relay is closed: the lamp switches on. Removing the hand the relay is opened and the lamp goes off.

Filter Blog

By date: By tag: