Go Down

Topic: Voice Recognition Light Dimmer; can't figure out two simultaneous loops (Read 828 times) previous topic - next topic

rojo20

Hello Arduino community.  First off, thanks in advance for any  help you can provide me with the following code.  It is extremely appreciated.  Coding is very difficult for me.

Current state: I have combined an Arduino Uno R3 with an EasyVR voice recognition module: http://www.veear.eu/products/easyvr-arduino-shield/ and an inmojo dimmer module: http://www.inmojo.com/store/inmojo-market/item/digital-ac-dimmer-module-lite-v.2/.

I am successfully turning on and off my lamp using my voice trigger command followed by my light on/off voice commands.  Essentially, a recognized voice trigger followed by a recognized voice command switches the 'lightPin' (output 3) from HIGH to LOW.  The recognizeWord() and getWord() functions are continuously looping to listen to further commands.

However, I cannot figure out how to integrate the dimmer code (which also runs a loop) to run simultaneously with the voice recognition loop.  Dimming requires its own loop because this function is continuously writing the 'lightPin' to HIGH and LOW depending on speed.

I have researched the 'blink without delay' example, timer functions, millis (), and even thread libraries, but I can't get anything to work, nor do I know how to properly integrate those functions into my code.

My goal is to be able to say a trigger command followed by a voice command that dims the lamp AND continues to listen for more commands (Light On, Light Off, Brighter, Dimmer, Dim 25%, Dim 50%, Dim 75%).

GRAMMAR_4  = voice trigger, GRAMMAR_5 = voice commands

I have pasted both code sets below.  If anyone can review and provide help, that would be awesome.  Unfortunately, I am not a coder.  I only have respect for those who are.  If any more information is required, please let me know.  Thanks again!

Voice Recognition with On/Off Commands

Code: [Select]
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#include "Platform.h"
#include "SoftwareSerial.h"
#ifndef CDC_ENABLED  // Shield Jumper on SW
SoftwareSerial port(12,13);
#else  // Shield Jumper on HW (for Leonardo)
#define port Serial1
#endif
#else // Arduino 0022 - use modified NewSoftSerial
#include "WProgram.h"
#include "NewSoftSerial.h"
NewSoftSerial port(12,13);
#endif

#include "EasyVR.h"
EasyVR easyvr(port);

enum Wordset
{
  GRAMMAR_4 = 4,
  GRAMMAR_5 = 5,
};

enum Grammar4
{
  G4_VOICELIGHT = 0,
};

enum Grammar5
{
  G5_LIGHT_OFF = 0,
  G5_LIGHT_ON = 1,
  G5_DIM_50 = 2,
};

EasyVRBridge bridge;

int8_t wordset, idx;
bool setKnob(int8_t knob);
bool setLevel(int8_t level);
int lightPin = 3;
long crossTime = 0;
long currentCycle = 0;
int dimming = 0;

void setup()
{
#ifndef CDC_ENABLED
 
  if (bridge.check())  // bridge mode?
  {
    cli();
    bridge.loop(0, 1, 12, 13);
  }
  // run normally
  Serial.begin(9600);
  //Serial.println("Bridge not started!");
#else
  if (bridge.check())  // bridge mode?
  {
    port.begin(9600);
    bridge.loop(port);
  }
  //Serial.println("Bridge connection aborted!");
#endif
  port.begin(9600);

  while (!easyvr.detect())
  {
    //Serial.println("EasyVR not detected!");
    //delay(1000);
  }
  easyvr.setPinOutput(EasyVR::IO1, LOW); 
  easyvr.setTimeout(5);
  easyvr.setLanguage(0);
  easyvr.setKnob(4);
  easyvr.setLevel(5);

  wordset = 4; //<-- start wordset (customize)

  pinMode(2,INPUT);
  pinMode(lightPin, OUTPUT);
  digitalWrite(lightPin, LOW);    // set the LED off
}

void loop()

  easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)
  Serial.print("Say a command in Wordset ");
  Serial.println(wordset);
  easyvr.recognizeWord(wordset);

  do
  {
    // can do some processing while waiting for a spoken command
  }
  while (!easyvr.hasFinished());

  easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

  idx = easyvr.getWord();

  if (idx >= 0)
  {
    easyvr.playSound(0, EasyVR::VOL_FULL);

    action();   // perform some action
  }
  else // errors or timeout
  {
    if (easyvr.isTimeout())

      Serial.println("Timed out, try again...");
    int16_t err = easyvr.getError();

    if (err >= 0)
    {
      Serial.print("Error ");
      Serial.println(err, HEX);

      wordset = 4;
    }
  }
}


void action()
{
  switch (wordset)
  {
  case GRAMMAR_4:
    switch (idx)
    {
     case G4_VOICELIGHT:

      wordset = GRAMMAR_5;   // <--  jump to another wordset X for composite commands
      break;
    }
    break;
 
  case GRAMMAR_5:
    switch (idx)
    {
     case G5_LIGHT_OFF:

      digitalWrite(lightPin, LOW);
      wordset = GRAMMAR_4;   //<--  jump to another wordset X for composite commands
      break;

    case G5_LIGHT_ON:

      digitalWrite(lightPin, HIGH);
      wordset = GRAMMAR_4;   // <-- jump to another wordset X for composite commands
      break;

    case G5_DIM_50:

      // **NOT SURE WHAT TO DO HERE**

      wordset = GRAMMAR_4;   // <--  jump to another wordset X for composite commands
      break;
    }
    break;
  }
}



Dimmer code

Code: [Select]
int lightPin = 3;
long crossTime = 0;
long currentCycle = 0;
int dimming = 0;

void setup()
{
pinMode(lightPin, OUTPUT);
pinMode(2,INPUT);
digitalWrite(lightPin,0);
}

void loop()
{
  if(digitalRead(2))
  {
    zeroCross();
    {
      dimming = 6150;
    }
  }
}

void zeroCross(){
crossTime = micros();
while((micros() - crossTime) < 8200){
currentCycle = micros() - crossTime;
if (currentCycle > dimming) digitalWrite(lightPin,1);
digitalWrite(lightPin,0);
}
}
- Technology can help -

LuisCRSousa

#1
Jun 29, 2014, 02:08 am Last Edit: Jun 29, 2014, 02:12 am by LuisCRSousa Reason: 1
I build my own dimmer, works the same way as that and i had to do more things with the arduino than just dimming.
I had to comunicate with anothers via UART, read sensors, activate relays, read keyboards etc..

So you have two options:
1) Use two arduinos. One for general functions, for your case to run your easyvr code, and another for just dimming the lights and communicate between. Like i did, because with dimmers the timming is essencial.
2) As i see, your code is not to big and complicated. What i see is you have to put your dimmer code inside the "do while" part.

Code: [Select]
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#include "Platform.h"
#include "SoftwareSerial.h"
#ifndef CDC_ENABLED  // Shield Jumper on SW
SoftwareSerial port(12,13);
#else  // Shield Jumper on HW (for Leonardo)
#define port Serial1
#endif
#else // Arduino 0022 - use modified NewSoftSerial
#include "WProgram.h"
#include "NewSoftSerial.h"
NewSoftSerial port(12,13);
#endif

#include "EasyVR.h"
EasyVR easyvr(port);

enum Wordset
{
 GRAMMAR_4 = 4,
 GRAMMAR_5 = 5,
};

enum Grammar4
{
 G4_VOICELIGHT = 0,
};

enum Grammar5
{
 G5_LIGHT_OFF = 0,
 G5_LIGHT_ON = 1,
 G5_DIM_50 = 2,
};

EasyVRBridge bridge;

int8_t wordset, idx;
bool setKnob(int8_t knob);
bool setLevel(int8_t level);
int lightPin = 3;
long crossTime = 0;
long currentCycle = 0;
int dimming = 0;

void setup()
{
#ifndef CDC_ENABLED
 
 if (bridge.check())  // bridge mode?
 {
   cli();
   bridge.loop(0, 1, 12, 13);
 }
 // run normally
 Serial.begin(9600);
 //Serial.println("Bridge not started!");
#else
 if (bridge.check())  // bridge mode?
 {
   port.begin(9600);
   bridge.loop(port);
 }
 //Serial.println("Bridge connection aborted!");
#endif
 port.begin(9600);

 while (!easyvr.detect())
 {
   //Serial.println("EasyVR not detected!");
   //delay(1000);
 }
 easyvr.setPinOutput(EasyVR::IO1, LOW);  
 easyvr.setTimeout(5);
 easyvr.setLanguage(0);
 easyvr.setKnob(4);
 easyvr.setLevel(5);

 wordset = 4; //<-- start wordset (customize)

 pinMode(2,INPUT);
 pinMode(lightPin, OUTPUT);
 digitalWrite(lightPin, LOW);    // set the LED off
}

void loop()
{  
 easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)
 Serial.print("Say a command in Wordset ");
 Serial.println(wordset);
 easyvr.recognizeWord(wordset);

 do
 {
    //i put this part
     if(digitalRead(2))
  {
    zeroCross();
    {
      dimming = 6150;
    }
  }
 }
 while (!easyvr.hasFinished());

 easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

 idx = easyvr.getWord();

 if (idx >= 0)
 {
   easyvr.playSound(0, EasyVR::VOL_FULL);

   action();   // perform some action
 }
 else // errors or timeout
 {
   if (easyvr.isTimeout())

     Serial.println("Timed out, try again...");
   int16_t err = easyvr.getError();

   if (err >= 0)
   {
     Serial.print("Error ");
     Serial.println(err, HEX);

     wordset = 4;
   }
 }
}


void action()
{
 switch (wordset)
 {
 case GRAMMAR_4:
   switch (idx)
   {
    case G4_VOICELIGHT:

     wordset = GRAMMAR_5;   // <--  jump to another wordset X for composite commands
     break;
   }
   break;
 
 case GRAMMAR_5:
   switch (idx)
   {
    case G5_LIGHT_OFF:

     digitalWrite(lightPin, LOW);
     wordset = GRAMMAR_4;   //<--  jump to another wordset X for composite commands
     break;

   case G5_LIGHT_ON:

     digitalWrite(lightPin, HIGH);
     wordset = GRAMMAR_4;   // <-- jump to another wordset X for composite commands
     break;

   case G5_DIM_50:

     // **NOT SURE WHAT TO DO HERE**

     wordset = GRAMMAR_4;   // <--  jump to another wordset X for composite commands
     break;
   }
   break;
 }
}



I dont know if this is correct, i didnt gone much deep in your code. I suggest you to attach an interrupt to pin 2 (zeroCrossDetection?) on the dimmer.

rojo20

Luis,

Thank you so much for your reply.   I very much appreciate your help.

I thought about using two arduinos, but I am trying to keep the size of the unit as small as possible.

I tried what you suggested with the code.  The lamp dims, but it flickers every time the code loops back to request the trigger command (approximately every 5 seconds).

In other words, the program waits for a trigger.  I say trigger.  I say dim command.  Lamp dims.  Then after every 5 seconds the lamp flickers when it loops back to ask for the trigger command again.

Any thoughts on how to stop the flicker?

- Technology can help -

rojo20

Hey Luis,

I figured it out.  I used a boolean and changed the timeout setting.  Thanks again for your help.  You pointed me in the right direction!  Sincerely, thanks very much!

Robb
- Technology can help -


Go Up