banner left Boxtec Banner
Platzhalter BoxtecProdukteForumShopKontaktPlaygroundn/aJobs
 

Voice Shield Slim Review

im Aufbau ...

Geliefert wurde ein Bausatz mit einer Platine (PCB) und vielen Bauteilen. Auf der Verpackung aufgedruckt ist die Materialliste und es waren alle Bauteile da. Hier ein Bild:

Oben links sieht man die Tantalkondensatoren (8), daneben eine LED, fünf Elkos und die Header. Darunter die Platine, die Audiostecker und der Poti. Daneben der Soundchip und der kleine Verstärkerchip. Zuletzt noch die Dioden und Widerstände.

Beim Löten muss man nicht Besonderes beachten, und wenn man der sehr schönen Anleitung folgt, kann eigentlich nichts schief gehen.

Auf zur Software: Die findet man bei SpikenzieLabs, wobei man bis ans Ende scrollen muss. Geladen habe ich die Library, die Sound Dateien und den programmer sowie die Lite Version, alles für Windows. Die Anleitung empfiehlt, die Library unter Arduino\Hardware\Libraries zu installieren. Ich nehme lieber das Standardverzeichnis unter c:\Users\userid\Documente\Arduino\libraries. Danach soll man das Sketch VSLoader laden, was problemlos klappt.

Jetzt soll man den Programmer installiern, was auch kein Problem ist. Die Sounddateien werden in den entsprechenden Ordner kopiert. Dabei sollte man die Schritte der Anleitung beachten. Nach dem Start des Programms konnte ich mich ohne Probleme mit dem Arduino, der das Shield trägt, verbinden. Dann habe ich die Sounddateien hoch geladen. Dazu braucht es ein Audiokabel mit 3.75 Klinkesteckern, das ich zum Glück hatte.

Das Laden hat geklappt und mit einem angeschlossenen Lautsprecher kann man die einzelnen Sounds abspielen.

Zwischenfazit

Das VoiceShield ist einfach zu löten und genauso einfach in Betrieb zu nehmendes Shield. Es macht Spaß, es zu löten und die Worte aus dem Lautsprecher zu hören als Bestätigung, dass man alles richtig gemacht hat. Jetzt geht es an die Programmierung (also die Beispiele der Library).

Beispiel BasicPhraseTalk

Ich habe den Sketch geladen, übersetzt und in den Arduino geladen. Der Code ist klar verständlich und vor allem richtig. Ich habe “upload” geklickt und das Shield fing an zu sprechen! Alles in Allem ein sehr einfaches und tolles Shield!

Sprechende Uhr

Ich habe den Code der TextClock meines Vaters geladen, der eine Wortuhr auf einem TFT Display darstellt und als neuen Sketch abgespeichert. Dann habe ich alle Verweise entfernt, was mit dem LCD zu tun hat, da ich ja eine sprechende Uhr haben will und nicht eine zeichnende. Außerdem braucht das TFT Display alle Pins des Arduinos und daher kann ich das VoiceShield nicht zusammen mit einem TFT betreiben. Bei der Gelegenheit frage ich mich, welche Pins das Shield eigentlich belegt. Laut Arduino Shield List: VoiceShield Slim belegt das Shield die Pins D2, D3, D4 und D5.

Dann habe ich die Wörter mit den Soundbytes der VoiceShield Software verbunden, genau so, wie im Beispielprogramm angegeben. Dabei hat mir mein Vater geholfen.

Die TextClock wechselt alle 5 Minuten die Anzeige. Diesen Moment habe ich dazu verwendet, um die Uhrzeit als Sound auszugeben. Zum Testen, haben wir aber die Minuten an die Sekunden gekoppelt, so dass alle 5 Sekunden die Uhrzeit als Sprache ausgegeben wurde.

Leider habe wir für die Worte “half”, “quarter”, “past” und “minute” keine passenden Sounds gefunden. Also muss als nächstes ausprobiert werden, wie man Soundfile aufnimmt. Dabei werde ich auch gleich eine deutsche Version aufnehmen.

Soundfiles aufnehmen: Balabolka

Ich habe mit meinem Vater lange im Internet gesucht und wir sind auf ein nettes Programm gestoßen: Balabolka. Das ist russisch und bedeutet “Schwätzer” ;-) Man gibt den Text, den man vorgelesen haben will im Fenster ein und setzt den Cursor an den Anfang. Dann kann man sich den Text anhören. Dabei fällt auf, dass der Text mit einem schrecklichen amerikanischen Akzent vorgelesen wird. Das liegt daran, dass unser Windowssystem nur diese Stimme ausliefert. Man kann aber eine deutsche Stimme nachinstallieren. Die entsprechenden Links sind auf der Homepage von Balabolka zu finden. Mit diesem Programm haben wir die einzelnen Soundbytes zusammen gestellt. Da die VoiceShield Software mp3 versteht muss man die Audiodateien als solche abspeichern oder umwandeln. Balabolka bietet mp3 direkt an.

Nun müssen die Soundbytes der VoiceShield Software durch die neuen Files ersetzt werden. Lange haben mein Vater und ich versucht, das Programm mit den neuen Dateien zu starten und erst nach einiger zeit haben wir heraus gefunden, dass das Programm immer die Datei Monkey2.aiff sucht und ohne diese Datei im Soundbyte Verzeichnis nicht starten will.

Das zugehörige Definitionsfile soundscore.txt sieht dann so aus:

0	esist.mp3
1	fuenfnach.mp3
2	zehnnach.mp3
3	viertelnach.mp3
4	zwanzignach.mp3
5	fuenfundzwanzignach.mp3
6	halb.mp3
7	fuenfnachhalb.mp3
8	zwanzigvor.mp3
9	viertelvor.mp3
10	zehnvor.mp3
11	fuenfvor.mp3
12	einuhr.mp3
13	zweiuhr.mp3
14	dreiuhr.mp3
15	vieruhr.mp3
16	fuenfuhr.mp3
17	sechsuhr.mp3
18	siebenuhr.mp3
19	achtuhr.mp3
20	neunuhr.mp3
21	zehnuhr.mp3
22	elfuhr.mp3
23	zwoelfuhr.mp3
24	willkommen.mp3

Im arduino code kann man das entsprechende Soundbyte durch den Aufruf:

  vs.ISDPLAY_to_EOM(24);

abspielen. Die 24 spielt also den Willkommensgruß ab.

Die Soundfiles werden von der Software in den Soundchip dadurch geladen, dass der Kopfhörerausgang des PCs mit Audio-In des VoiceShields verbunden wird. Das Programm spielt dann die entsprechenden Dateien ab und nimmt sie in den Soundchip auf. Dabei haben wir entdeckt, dass Dateien größer als 43 kB nicht richtig geladen werden und dann später auch nicht richtig abgespielt werden. Zu lange Dateien erkennt man daran, dass das Programm flackert. Außerdem habe ich die Lautstärke auf 25% herunter geregelt, da sonst die Sounds übersteuert sind.

Hier noch der Code für das SpeakClock:

/*
 SpeakClock.ino - Clock using an Arduino and the Spikenzielabs VoiceShield 
 http://www.spikenzielabs.com/Catalog/index.php?main_page=product_info&cPath=27&products_id=211
 Copyright (C)2013 Dr. Mathias Wilhelm. All right reserved
 
 If you make any modifications or improvements to the code, I would 
 appreciate that you share the code with me so that I might include 
 it in the next release. I can be contacted through 
 http://www.mathias-wilhelm.de/arduino
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU Lesser General Public
 License as published by the Free Software Foundation; either
 version 2.1 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 Lesser General Public License for more details.
 */
#include <VoiceShield.h>
VoiceShield vs(80);
#include <DS1307.h>

#define StartTag   83  // S-Zeichen
#define EndTag     69  // E-Zeichen

DS1307 rtc(4, 5); // define your RTC here

boolean c_debug = true;
boolean c_demo = true;
//boolean c_rtc=true; // use rtc clock
boolean c_rtc = false; // do not use rtc clock

long t_ms;
Time t;

int lastsec=0;
int lastmin=0;
boolean sec_highlight=false;
boolean min_highlight=false;
boolean initialized=false;
int bufferCount;    // Anzahl der eingelesenen Zeichen
char buffer[20];    // Serial Input-Buffer

/********************************************************
 * standard setup routine
 ********************************************************/
void setup() {
  t.hour = 0;
  t.min = 0;
  t.sec = 0;
  t.date = 0;
  t.mon = 0;
  t.year = 0;
  t.dow = 0;
  // Set the clock to run-mode
  rtc.halt(false);

  // wait for time set to initialize
  Serial.begin(9600);
  Serial.println("Enter time ticket to set time");
  Serial.println("Format: ShhmmssddmmyyyyE");
  Serial.println("SDEMOE to toggle demo mode");
  Serial.println("SRTCE  to toggle RTC mode");
  Serial.println("SDEBUGE  to toggle debug mode");
  t_ms = millis();
  delay(1000);
  if (c_debug) Serial.println("SpeakClock started");
  vs.ISDPLAY_to_EOM(24);
}

/********************************************************
 * standard loop routine
 ********************************************************/
void loop() {
  int speak;
  c_update();
  if (t.sec != lastsec){
    lastsec = t.sec;
    speak = t.min %5;
    if (speak==0) c_setMatrix();
    if (c_debug){ 
      if(t.hour<10) Serial.print('0');
      Serial.print(t.hour);
      Serial.print(":");
      if(t.min<10) Serial.print('0');
      Serial.print(t.min);
      Serial.print(":");
      if(t.sec<10) Serial.print('0');
      Serial.print(t.sec);
      Serial.println(" ");
    }
  }
  if (t.min != lastmin){
    lastmin = t.min;
  }
}

/********************************************************
 * serial event routine
 ********************************************************/
void serialEvent(){
  char ch = Serial.read();
  buffer[bufferCount] = ch;
  bufferCount++;
  if(ch == 13)
    evalSerialData();
}

/********************************************************
 * parse serial input
 ********************************************************/
void evalSerialData(){
  boolean sok = false;
  // toggle debug mode
  if((buffer[0] == StartTag) && (buffer[6] == EndTag))
  {
    if ((buffer[1] == 'D') && (buffer[2] == 'E') && (buffer[3] == 'B') && (buffer[4] == 'U') && (buffer[5] == 'G'))
    {
      sok = true;
      c_debug = !c_debug;
      if (c_debug) {
        Serial.println("Switched to DEBUG mode");
      } 
      else {
        Serial.println("Switched back to normal mode");
      }
    }
  }
  // toggle RTC mode
  if((buffer[0] == StartTag) && (buffer[4] == EndTag))
  {
    if ((buffer[1] == 'R') && (buffer[2] == 'T') && (buffer[3] == 'C'))
    {
      sok = true;
      c_rtc = !c_rtc;
      if (c_rtc) {
        Serial.println("Using RTC clock");
        t = rtc.getTime();
      } 
      else {
        Serial.println("Using Arduino clock");
      }
    }
  }
  // toggle demo mode
  if((buffer[0] == StartTag) && (buffer[5] == EndTag))
  {
    if ((buffer[1] == 'D') && (buffer[2] == 'E') && (buffer[3] == 'M') && (buffer[4] == 'O'))
    {
      sok = true;
      c_demo = !c_demo;
      if (c_demo) 
      {
        if (c_rtc) c_rtc=false;
        Serial.println("Minutes linked to seconds for Demo");
        Serial.println("RTC reading switched off  for Demo");
      } 
      else 
      {
        Serial.println("Switched to normal time mode");
        Serial.println("Remember to switch clock back to RTC");
      }
    }
  }
  // serial time ticket: ShhmmssddmmyyyyE
  //                     0123456789012345
  //                               111111
  // i.e. S15364318092012E
  if((buffer[0] == StartTag) && (buffer[15] == EndTag))
  {
    sok = true;
    t.hour = (buffer[ 1] - 48) * 10 + (buffer[2] - 48);
    t.min  = (buffer[ 3] - 48) * 10 + (buffer[4] - 48);
    t.sec  = (buffer[ 5] - 48) * 10 + (buffer[6] - 48);
    t.date = (buffer[ 7] - 48) * 10 + (buffer[8] - 48);
    t.mon  = (buffer[ 9] - 48) * 10 + (buffer[10] - 48);
    t.year = (buffer[11] - 48) * 1000 + (buffer[12] - 48) * 100 + (buffer[13] - 48) * 10 + (buffer[14] - 48);
    t.hour = constrain(t.hour,0,23);
    t.min  = constrain(t.min ,0,59);
    t.sec  = constrain(t.sec ,0,59);
    t.date = constrain(t.date,0,31);
    t.mon  = constrain(t.mon ,0,12);
    t.year = constrain(t.year,0,9999);
    Serial.print("Time set to : ");
    if(t.hour<10) Serial.print('0');
    Serial.print(t.hour);
    Serial.print(":");
    if(t.min<10) Serial.print('0');
    Serial.print(t.min);
    Serial.print(":");
    if(t.sec<10) Serial.print('0');
    Serial.print(t.sec);
    Serial.print(" - ");
    if(t.date<10) Serial.print('0');
    Serial.print(t.date);
    Serial.print(".");
    if(t.mon<10) Serial.print('0');
    Serial.print(t.mon);
    Serial.print(".");
    Serial.print(t.year);
    Serial.println(" ");
    if (c_rtc) {
      rtc.setTime(t.hour,t.min,t.sec);
      rtc.setDate(t.date,t.mon,t.year);
    }
  }
  if (!sok) {
    Serial.print("Invalid Serial Command :");
    for (int i=0; i<bufferCount; i++) Serial.print(buffer[i]);
    Serial.println(" received");
  }
  buffer[0] = '.'; 
  buffer[5] = '.'; 
  buffer[15] = '.'; // Buffer invalid setzen
  bufferCount = 0;                  // Reset Buffer Counter
}

/********************************************************
 * fill Matrix routines (called Matrix as the original code was displaying a text matrix)
 ********************************************************/
void c_setMatrix(){
  int c_hour;
  c_hour = t.hour % 12;
  switch (t.min / 5) {
  case 0:
    // glatte Stunde
    vs.ISDPLAY_to_EOM(0);
    break;
  case 1:
    // 5 nach
    vs.ISDPLAY_to_EOM(1);
    break;
  case 2:
    // 10 nach
    vs.ISDPLAY_to_EOM(2);
    break;
  case 3:
    // viertel
    vs.ISDPLAY_to_EOM(3);
    break;
  case 4:
    // 20 nach
    vs.ISDPLAY_to_EOM(4);
    break;
  case 5:
    // 5 vor halb
    vs.ISDPLAY_to_EOM(5);
    break;
  case 6:
    // halb
    vs.ISDPLAY_to_EOM(6);
    c_hour++;
    break;
  case 7:
    // 5 nach halb
    vs.ISDPLAY_to_EOM(7);
    c_hour++;
    break;
  case 8:
    // 20 vor
    vs.ISDPLAY_to_EOM(8);
    c_hour++;
    break;
  case 9:
    // dreiviertel
    vs.ISDPLAY_to_EOM(9);
    c_hour++;
    break;
  case 10:
    // 10 vor
    vs.ISDPLAY_to_EOM(10);
    c_hour++;
    break;
  case 11:
    // 5 vor
    vs.ISDPLAY_to_EOM(11);
    c_hour++;
    break;
  }
  if (c_hour>11) c_hour=0; 
  switch (c_hour) {
  case 0:
  case 12:
    vs.ISDPLAY_to_EOM(23);
    break;
  case 1:
    vs.ISDPLAY_to_EOM(12);
    break;
  case 2:
    vs.ISDPLAY_to_EOM(13);
    break;
  case 3:
    vs.ISDPLAY_to_EOM(14);
    break;
  case 4: 
    vs.ISDPLAY_to_EOM(15);
    break;
  case 5: 
    vs.ISDPLAY_to_EOM(16);
    break;
  case 6: 
    vs.ISDPLAY_to_EOM(17);
    break;
  case 7: 
    vs.ISDPLAY_to_EOM(18);
    break;
  case 8: 
    vs.ISDPLAY_to_EOM(19);
    break;
  case 9: 
    vs.ISDPLAY_to_EOM(20);
    break;
  case 10: 
    vs.ISDPLAY_to_EOM(21);
    break;
  case 11: 
    vs.ISDPLAY_to_EOM(22);
    break;
  }
}

/********************************************************
 * clock update routines
 ********************************************************/
void c_update(){
  long ctime;
  int elapsed;
  int daypermonth[12] = {
    31,28,31,30,31,30,31,31,30,31,30,31            };
  if (!c_rtc){
    ctime = millis();
    elapsed= (ctime - t_ms)/1000;
    if (elapsed>0) {
      t_ms = ctime;
      t.sec = t.sec + elapsed;
      if (c_demo) t.min++; // DEBUG ONLY ADVANCE TIME FASTER
      if (t.sec>59){
        t.sec = 0;
        t.min++;
      }
      if (t.min>59){
        t.min = 0;
        t.hour++;
      }
      if (t.hour>23){
        t.hour = 0;
        t.date++;
        t.dow++;
      }
      if (t.date>daypermonth[t.mon-1]){
        t.mon = 1;
        t.year++;
      }
      if (t.dow>6) t.dow=0;
    }
  } 
  else {
    t = rtc.getTime();
  }
}
 
reviews/voiceshield.txt · Last modified: 2013/05/30 12:48 by mathiasw
 
 

zum Seitenanfang

Letzte Aktualisierung: © boxtec internet appliances · the better security products