Thursday, March 29, 2018

RFID and Wemos D1 mini (1)

I wanted to connect an RFID reader to my home network.
Therefore i used a ESP8266, more specific the Wemos D1 mini Wifi module.

Test 1 (fail)

I found a project on http://www.instructables.com/id/WiFi-RFID-Reader/ using a Wemos D1 mini. The exact info about the pins was missing.
As a test i created the circuit as a test on a breadboard using the Wemos D1 mini pin info on https://escapequotes.net/esp8266-wemos-d1-mini-pins-and-diagram/. (See also this picture with Wemos D1 mini connections)




RFIDESP8266Wemos D1 mini
RSTGPIO05 (free GPIO)D1
SSGPIO4 (free GPIO)D2
MOSIGPIO13 (HW SPI)D7
MISOGPIO12 (HW SPI)D6
SCKGPIO14 (HW SPI)D5
GNDGNDG
3.3V3.3V3V3
The instructional also contains software to read basic RFID info and send it over the serial (usb) line.

define RFID module

#include "MFRC522.h"
#define RST_PIN 15 // RST-PIN for RC522 - RFID - SPI - Modul GPIO15 
#define SS_PIN  2  // SDA-PIN for RC522 - RFID - SPI - Modul GPIO2
MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

Initialize RFID module

void setup() {
  Serial.begin(9600);    // Initialize serial communications
  SPI.begin();           // Init SPI bus
  mfrc522.PCD_Init();    // Init MFRC522 
}

Read RFID tag

void loop() { 
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    delay(50);
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    delay(50);
    return;
  }
  // Show some details of the PICC (that is: the tag/card)
  Serial.print(F("Card UID:"));
  dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.println();
}

// Helper routine to dump a byte array as hex values to Serial
void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}
Unfortunate the example above did not working for me. I got output on the terminal, however there was a message about perhaps bad connections.

Test 2 (succes)

More succesfull was the next example that  i found this on github:
https://github.com/Jorgen-VikingGod/ESP8266-MFRC522

Wiring RFID RC522 module

The following table shows the typical pin layout used:
SignalMFRC522WeMos D1 miniNodeMcuGeneric
RST/ResetRSTD3 [1]D3 [1]GPIO-0 [1]
SPI SSSDA [3]D8 [2]D8 [2]GPIO-15 [2]
SPI MOSIMOSID7D7GPIO-13
SPI MISOMISOD6D6GPIO-12
SPI SCKSCKD5D5GPIO-14
  • [1] (1, 2) Configurable, typically defined as RST_PIN in sketch/program.
  • [2] (1, 2) Configurable, typically defined as SS_PIN in sketch/program.
  • [3] The SDA pin might be labeled SS on some/older MFRC522 boards (including the one i used)

Define RFID module

#include "MFRC522.h"
#define RST_PIN 5 // RST-PIN for RC522 - RFID - SPI - Modul GPIO5 
#define SS_PIN 4 // SDA-PIN for RC522 - RFID - SPI - Modul GPIO4 
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance

Initialize RFID module

void setup() {
  Serial.begin(115200);    // Initialize serial communications
  SPI.begin();          // Init SPI bus
  mfrc522.PCD_Init();    // Init MFRC522
}

Read RFID tags

void loop() { 
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    delay(50);
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    delay(50);
    return;
  }
  // Show some details of the PICC (that is: the tag/card)
  Serial.print(F("Card UID:"));
  dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
  Serial.println();
}

// Helper routine to dump a byte array as hex values to Serial
void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}
THis did work and i expected that was a good starting point for the rest of my project.

Saturday, March 17, 2018

Voice Control V3 (2) Software intro

Due to some other activities it has been a while ago that i made my last post. This post is an introduction to the software for the Voice Control V3 Module.
The Voice Control V3 module is a relative cheap module that can recognize 80 words/phrases. However it only can recognize 7 words/phrases at the same time. To recognize sound you first need to train the words/phrases in a training mode. In the recognition mode you can load the phrase identification numbers in special registers. ( I now will use the word phrase in this post but it can also be s word or another sound).
After this the module waits until the trained phrase is recognized and sends a signal.
I used the state machine idea in he software..
Each state has an id, the state id. When the system starts it starts in state one.
When a (new) voice recognition state is entered the 7 phrase id's are loaded in the module and the software waits until one of the 7 phrases is recognized..
When a phrase is recognized two things need to happen:
- An action is performed
- The machine enters a new state. (In this new voice recognition state the seven new (other) phrases are loaded, the module starts listening to [other] phrases until the module comes again in a new state.)
Each state also has a timeout. When no matching phrase has been recognized before a certain time this also triggers entering a new state and action to be performed.

State table for state(n)
State Input Load Output Output
StateN 1 PhraseId ActionId NewStateId
StateN 2 PhraseId ActionId NewStateId
StateN 3 PhraseId ActionId NewStateId
StateN 4 PhraseId ActionId NewStateId
StateN 5 PhraseId ActionId NewStateId
StateN 6 PhraseId ActionId NewStateId
StateN 7 PhraseId ActionId NewStateId
StateN TimeOut TIME ActionId NewStateId

When the actions are programmed the system can be configured loading a data table containing info about the PhraseId's, ActionId's, StateId's for each state like the state table above.
To make the software more robust i want to do the actions at the beginning of the new state after setting the timer for the timeout not at the end. Therefore after receiving the input trigger i immediate change state and pass the ActionId of the action that needs to be executed to the new state.
Steps after entering a new state are:
1) Set the timer for TimeOut.
2) Load new PhraseId's in the voice module.
3) Do the action (that need to be done due to the previous state change).
4) Wait for the new input triggers.
The details can be loaded from a table and some variables like the Previous_ActionId.
TimeOut also protects for timeout of the actions as it is set before the execution of the action. If needed an action can modify or stop and later restart the watchdog timer to give it more time to execute.
Changing a state can only trigger one action. To facilitate execution of multiple actions after receiving a trigger special states are added: A (numerical) range of states do not load PhraseId's and wait for voice command. This states only execute the actions. When the action is ended it immediately enters a new state. 
Special states are also:
0 stop  No actions are executed. The system stops. 
1 boot No actions are executed. All variables are reset This is the first state that will be executed when system powers up. 
Besides the voice input and timeout other triggers can be used to change the state. The module can have hardware like (one one multiple) push buttons or an IRreceiver.
Actions that can be performed also depend on the other hardware. The most simple action is a dummy action that does nothing. Other actions can be e.g. a led (color or blinking), a buzzer to give visual or audio feedback. An IR-transmitter can sends out a IR remote control code, a 433MHz transmitter or bluetooth transmitter for a radio control signal or if connected to an network e.g. a http://request.
Other special actions that could be added are learning actions to learn a new voice command or a IR control code.
However the best is not to make your voice recognizer to complex. Let your home automation system control of your home hardware. Let the voice recognizer module communicate to your home automation system. (and only add a led and a buzzer for some feedback.)
To connect the Voice Recognizer V3 to your home automation system using Wifi is a (simple and cheap)  ESP8266 module (e.g. the Wemos D1 mini) can be used. This will be presented in one of the next posts about this topic.