Pages: [1]   Go Down
Author Topic: Voice Recognition Light Dimmer; can't figure out two simultaneous loops  (Read 816 times)
0 Members and 1 Guest are viewing this topic.
Michigan
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Technology can help.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
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);
}
}
Logged

- Technology can help -

Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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.
« Last Edit: June 28, 2014, 07:12:50 pm by LuisCRSousa » Logged

Michigan
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Technology can help.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?

Logged

- Technology can help -

Michigan
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Technology can help.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

- Technology can help -

Offline Offline
Newbie
*
Karma: 1
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're welcome smiley
Logged

Pages: [1]   Go Up
Jump to: