Room automation project

Hello all,
I am doing room automation project with ELECHOUSE Voice Recognition Module V3.

And besides I have very basic knowledge of programing, I got this system to work, but there is 1 problem. But first about the system: I am using V3 module to switch on and off 3 things:

  1. Room main light (with servo)
  2. Room night light (with reley)
  3. Sound amplifier for the music (with servo)

You could wonder why I am using servos and not relays for all that stuff, its because its not my house and i do not want to disassemble main room switches etc... But that doesn't matter. Servos working well in my case, they physically switching on/off other switches.

The problem with V3 module is that if you record sound commands in quiet conditions and near the microphone. Later you have to shout in the room and recognition is quite poor. If you recording commands from about 2m. distance, later recognition is much better, but if you are watching movies o listening music (especially louder) the system goes nuts and recognizes commands then it shouldnt that at least few times in half a hour. What I want to do is simply take 1 voice command for system to listen for lets say 10 sec for other 6 commands (3 on/off switching commands), and after that time system will listen again for that specific 1 voice command. As I said I have very basics of programming, so need your help guys. This is my working code so far and it needs to be a little adjusted, but I dont know how to add this functionality.

#include <SoftwareSerial.h>
#include "VoiceRecognitionV3.h"
#include <Servo.h>
Servo servo1;
Servo servo2;
VR myVR(12, 13);    // 2:RX 3:TX, you can choose your favourite pins.
uint8_t records[7];
uint8_t buf[64];
int led = 13;
int in1 = 5; //rele1
int in2 = 6; //rele2
#define lightON (0)
#define lightOFF (1)
#define switchON (2)
#define switchOFF (3)
#define soundON (4)
#define soundOFF (5)
#define listeningON (6)
/**
  @brief   Print signature, if the character is invisible, 
           print hexible value instead.
  @param   buf     --> command length
           len     --> number of parameters
*/
void printSignature(uint8_t *buf, int len)
{
    int i;
    for(i = 0; i < len; i++) {
        if (buf[i]>0x19 && buf[i]<0x7F) {
            Serial.write(buf[i]);
        } else {
            Serial.print("[");
            Serial.print(buf[i], HEX);
            Serial.print("]");
        }
    }
}
/**
  @brief   Print signature, if the character is invisible, 
           print hexible value instead.
  @param   buf  -->  VR module return value when voice is recognized.
             buf[0]  -->  Group mode(FF: None Group, 0x8n: User, 0x0n:System
             buf[1]  -->  number of record which is recognized. 
             buf[2]  -->  Recognizer index(position) value of the recognized record.
             buf[3]  -->  Signature length
             buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf)
{
    Serial.println("VR Index\tGroup\tRecordNum\tSignature");
    Serial.print(buf[2], DEC);
    Serial.print("\t\t");
    if (buf[0] == 0xFF) {
        Serial.print("NONE");
    } else if (buf[0]&0x80) {
        Serial.print("UG ");
        Serial.print(buf[0]&(~0x80), DEC);
    } else {
        Serial.print("SG ");
        Serial.print(buf[0], DEC);
    }
    Serial.print("\t");
    Serial.print(buf[1], DEC);
    Serial.print("\t\t");
    if (buf[3] > 0) {
        printSignature(buf+4, buf[3]);
    } else {
        Serial.print("NONE");
    }
    Serial.println("\r\n");
}
void setup()
{
    myVR.begin(9600);
    Serial.begin(115200);
    Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");
    pinMode(led, OUTPUT);
    pinMode(in1, OUTPUT);
    servo1.attach(9);
    servo2.attach(8);
    servo1.write(90);
    servo2.write(90);
  digitalWrite(in1, HIGH);
  pinMode(in2, OUTPUT);
  digitalWrite(in2, HIGH);
    if (myVR.clear() == 0) {
        Serial.println("Recognizer cleared.");
    } else {
        Serial.println("Not find VoiceRecognitionModule.");
        Serial.println("Please check connection and restart Arduino.");
        while(1);
    }
    if (myVR.load((uint8_t)lightON) >= 0) { 
        Serial.println("rele1on loaded");
    }
    if (myVR.load((uint8_t)lightOFF) >= 0) {
        Serial.println("rele1off loaded");   
    }
    if (myVR.load((uint8_t)switchON) >= 0) {
        Serial.println("sviesaON loaded");
    }
    if (myVR.load((uint8_t)switchOFF) >= 0) {
        Serial.println("sviesaOFF loaded"); 
    }
    if (myVR.load((uint8_t)soundON) >= 0) {
        Serial.println("stipON loaded"); 
    }
    if (myVR.load((uint8_t)soundOFF) >= 0) {
        Serial.println("stipOFF loaded"); 
    }
    if (myVR.load((uint8_t)LinsteningON) >= 0) {
        Serial.println("viskasOFF loaded"); 
    }
}
void loop()
{
    int ret;
    ret = myVR.recognize(buf, 50);
    if (ret > 0) {
        switch(buf[1]){                 
            case lightON:
                digitalWrite(in1, HIGH);
                break;
            case lightOFF:
                digitalWrite(in1, LOW);
                break;
            case switchON:
                digitalWrite(in2, LOW);
                delay (300);
                servo1.write(140);
                delay (500);
                servo1.write(90);
                delay (500);
                digitalWrite(in2, HIGH);
                break;
            case switchOFF:
                digitalWrite(in2, LOW);
                delay (300);
                servo1.write(40);
                delay (500);
                servo1.write(90);
                delay (500);
                digitalWrite(in2, HIGH);
                break;
            case soundON:
                digitalWrite(in2, LOW);
                delay (300);
                servo2.write(90);
                delay (500);
                digitalWrite(in2, HIGH);
                break;
            case soundOFF:
                digitalWrite(in2, LOW);
                delay (300);
                servo2.write(30);
                delay (500);
                digitalWrite(in2, HIGH);
                break;
            default:
                Serial.println("Record function undefined");
                break;
        }
        printVR(buf);
    }
}

I think only one thing with "IF" statment for some time must be added somethere before these commands:

case lightON:
                digitalWrite(in1, HIGH);
                break;
            case lightOFF:
                digitalWrite(in1, LOW);
                break;
            case switchON:
                digitalWrite(in2, LOW);
                delay (300);
                servo1.write(140);
                delay (500);
                servo1.write(90);
                delay (500);
                digitalWrite(in2, HIGH);
                break;
            case switchOFF:
                digitalWrite(in2, LOW);
                delay (300);
                servo1.write(40);
                delay (500);
                servo1.write(90);
                delay (500);
                digitalWrite(in2, HIGH);
                break;
            case soundON:
                digitalWrite(in2, LOW);
                delay (300);
                servo2.write(90);
                delay (500);
                digitalWrite(in2, HIGH);
                break;
            case soundOFF:
                digitalWrite(in2, LOW);
                delay (300);
                servo2.write(30);
                delay (500);
                digitalWrite(in2, HIGH);
                break;
            default:

rele_ir_servo_final_be_time.ino (4.82 KB)

It sounds like a Finite State Machine (FSM) would do what you want.

Sounds scary but isn't. Use switch/case and have the code in a WAITING case wait until the trigger phrase is heard then switch to a RESPONDING case to wait for a command for a period. Use millis() to time the period so that code execution is not blocked. If a command is received then act on it and return to the WAITING state, similarly if the period ends.

If you are not familiar with using millis() for timing then you may find
Using millis() for timing. A beginners guide useful.

UKHeliBob:
It sounds like a Finite State Machine (FSM) would do what you want.

Sounds scary but isn't. Use switch/case and have the code in a WAITING case wait until the trigger phrase is heard then switch to a RESPONDING case to wait for a command for a period. Use millis() to time the period so that code execution is not blocked. If a command is received then act on it and return to the WAITING state, similarly if the period ends.

If you are not familiar with using millis() for timing then you may find
Using millis() for timing. A beginners guide useful.

Thanx for the reply and i understand what do you mean and I imagining by myself somehow like you described, but the problem is that i am really quite shitty programmer i know that i need only maybe 4 or some code lines to add here, but it will be difficult to me and it will take maybe more than a day, because - ye I dont even familiar with that mills() function I can even send lets say 3 euros (through paypal or revolut) to some, who will add these few additional lines :slight_smile:

I can even send lets say 3 euros (through paypal or revolut) to some, who will add these few additional lines

You might get a better response if this thread were moved to the Gigs and Collaborations section of the forum.

Click "Report to moderator" and ask for it to be moved if that is what you want.

Ok, thanx again for these advises. I just think that money reward for someone maybe would be better choice than me - just wasting a lot of time... :slight_smile: