zaterdag 20 augustus 2016

De ogen van Zyptar

Een tijd geleden kwam er een doos spullen van feestbeest.nl binnen met onder andere een oog voor Zyptar (de andere wordt nageleverd).


Oog in een doosje
Ik heb de oogkassen van het hoofd een beetje verder ingeslepen zodat het oog goed past.


Oog gepast
Dus is  het nu tijd om na te denken over het oogmechaniek. Ik wil dat de ogen links-rechts en boven-beneden kunnen kijken. Ook wil ik de ogen er eng uit kunnen zien. Bijvoorbeeld door de oogbal zover weg te draaien dat je alleen wit ziet. Of door de ogen rood verlicht te maken. Dat laatste is niet zo moeilijk. Het oogwit is namelijk doorschijnend, dus als ik een rode lamp in de kop zet zie je de ogen waarschijnlijk al voldoende rood worden.


Ik ben eerst maar eens gaan kijken hoe anderen het doen. Onderstaand is een technisch mooi gemaakt en inspirerend voorbeeld.




Er vallen een paar constructies op:
  1. Het oog is bevestigd en draait om een cardankoppeling in het centrum van de oogbal.
  2. De ogen worden bewogen met dunne trek-duwstaafjes.
  3. De servo's voor links-rechts en op-neer zitten tussen de ogen. Deze staan daardoor nogal ver uit elkaar.
  4. Er zijn twee servo's voor de oogleden. Die kunnen dus in principe onafhankelijk dicht en open gaan. Je kunt er dus een knipoog mee geven.
  5. De oogbeweging is wel gekoppeld tussen de twee ogen. Je kunt er dus niet scheel mee kijken.
Zyptars ogen hebben geen beweegbare oogleden, dus ik zou aan twee servo's genoeg moeten hebben. Ik heb hele kleine servo's besteld (23 x 23 x 12,5 mm) voor dit doel. https://www.kiwi-electronics.nl/9g-micro-servo-pack .

De ogen van Feestbeest hebben en soort pen van 5,5 mm aan de achterkant zitten. Ik heb het idee om de ingewikkelde cardanas te vervangen door een stukje rubberslang dat ik over de pen schuif. Ik heb 5 x 7 siliconenrubberslang besteld. Dat zou net een beetje moeten knellen om de pen. Dan zet ik tegenover de pen van het oog een geprinte pen van 5,5 mm (die vast aan de kop zit) en verbindt de twee met de rubber slang.


Achterkant van het nep-oog
Dan kan ik mogelijk geen duwstang toepassen, want dan duw je de verbinding los. Wat ik dus wil doen is twee trekstangen aan het oog vastmaken, voor de links-rechtsbeweging en één voor de op-neer beweging. De verticale beweging moet dan op het veerkracht van het rubber terug naar de neutrale stand gaan. Zyptar kan dan alleen omhoog kijken. Niet naar beneden. Nu is dat misschien niet zo erg. Hij kan ook zijn nek bewegen om naar beneden te kijken.

Bijvoorbeeld als hij in trance gaat is het mooi als de ogen naar boven rollen.

Ik ben aan de slag gegaan met SketchUp om de onderdelen te tekenen en even later rolden ze uit de 3D-printer.
Het platform voor de ogen
De ogen worden aangedreven door twee mini-servo's. De twee servo's zijn aangesloten op de Arduino Mega. Daarna heb ik een sketch (programma) gemaakt dat de ogen laat rollen.

In de video zie je hoe dit werkt met één oog. Dit gaat nog aardig goed.


En in Zyptar's hoofd ziet het er al aardig griezelig uit.

Er ontstaan echter problemen wanneer je het tweede oog installeert.



De rubberslangophanging is te stug waardoor het tweede oog achterloopt. Er zit speling in het stangenmechaniek onder andere omdat het draad 0,8 mm is en de gaten 1,0 mm. Er moet dus eigenlijk toch een beter lager in.

Maar daarover volgende keer meer.




Weer een subsysteem van Zyptar: de stemgenerator

Voor het genereren van de stem van Zyptar gebruik ik de Emic 2 Text tot Speech generator. https://www.parallax.com/product/30016

Proefopstelling
De generator gebruikt een seriële poort, dus je hebt een schrijfpin en een leespin die je aan moet sluiten. Ik heb pin 51 en 53 gebruikt.


Er is een demoprogrammaatje van Joe Grand [www.grandideastudio.com]  dat ik een beetje heb aangepast.

#include <SoftwareSerial.h>
#define rxPin 51    // Serial input (connects to Emic 2 SOUT)
#define txPin 53    // Serial output (connects to Emic 2 SIN)
#define ledPin 13  // Most Arduino boards have an on-board LED on this pin
// set up a new serial port
SoftwareSerial emicSerial =  SoftwareSerial(rxPin, txPin);

void setup()  // Set up code called once on start-up
{

  // define pin modes
  pinMode(ledPin, OUTPUT);
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
 
  // set the data rate for the SoftwareSerial port
  emicSerial.begin(9600);
  digitalWrite(ledPin, LOW);  // turn LED off
 
  /*
    When the Emic 2 powers on, it takes about 3 seconds for it to successfully
    intialize. It then sends a ":" character to indicate it's ready to accept
    commands. If the Emic 2 is already initialized, a CR will also cause it
    to send a ":"
  */
  emicSerial.print('\n');             // Send a CR in case the system is already up
  while (emicSerial.read() != ':');   // When the Emic 2 has initialized and is ready, it will send a single ':' character, so wait here until we receive it
 delay(10);                          // Short delay

 
  emicSerial.flush();                 // Flush the receive buffer
}




void loop()  // Main code, to run repeatedly
{
  // Speak some text
  emicSerial.print("N1");
  emicSerial.print('\n');
  while (emicSerial.read() != ':');
  emicSerial.print('S');
  emicSerial.print("Whaaaat, this is an insult. Only twenty cents? You make Zoltar very angry");  // Send the desired string to convert to speech
  emicSerial.print('\n');

  digitalWrite(ledPin, HIGH);         // Turn on LED while Emic is outputting audio
  while (emicSerial.read() != ':');

  while(1)      // Demonstration complete!
  {
    delay(500);
    digitalWrite(ledPin, HIGH);
    delay(500);             
    digitalWrite(ledPin, LOW);
  }
}


Wat dit dus doet is de Emic 2 initialiseren en stem 1 kiezen (emicSerial.print("N1");). Dit is de stem met de meeste bas er in, dus het meest "mannelijk".


En dan zegt Zyptar:


Whaaaat, this is an insult. Only twenty cents? You make Zoltar very angry


Luister naar de video, dan hoor je hoe de generator klinkt.




Beetje zoals Stephen Hawkins. Ik weet niet of ik er zo blij mee ben. Misschien dat ik de teksten toch op ga nemen en als MP3 afspelen. Dat is wel veel meer werk. Hiermee hoef ik alleen tekstjes te typen.

Een bewegende mond voor Zyptar



Ik had de kaak al losgezaagd, maar hij moet nu ook ergens scharnieren en aangedreven worden.


Kaak
Een menselijke kaakbeen en scharniert een beetje naar achteren in je hoofd. Ik heb Zyptars kaak ook een beetje verlengd met een plaatje messing.


Ik heb een as dwars door de nek gestoken en met een geprint blokje als scharnier werkt dit redelijk.



As 3 mm messing staf en geprint scharnierblokje






Zo ziet het er dan uit.



donderdag 18 augustus 2016

Subsystemen voor Zyptar: De muntautomaat

Zyptar, de toekomstvoorspeller in een doos, werkt wanneer je er geld in gooit. Eigenlijk is Zyptar alleen maar bedoeld voor gasten die betalen voor een consumptie. In plaats van je geld op een schoteltje te leggen kun je het aan Zyptar schenken. Een consumptie kost 50 cent tot een euro en dat moet je dus kunnen "afrekenen".


De muntautomaat is een CH-924 van Adafruit. Hij kan vier munten onderscheiden.


Deze muntautomaat geeft pulsen af als er een munt doorheen komt en je kunt bepalen hoeveel pulsen overeenkomen met een bepaald bedrag.


De muntautomaat
Ik wil het zo maken dat Zyptar afhankelijk van het bedrag iets anders doet. Bij 20 cent voelt hij zich beledig en scheldt hij je uit bijvoorbeeld.


Daarom moet ik mijn vier munten goed kiezen, bijvoorbeeld:


1 euro: 10 pulsen
50 cent: 5 pulsen
20 cent: 2 pulsen
10 cent: 1 puls


Dit betekent dat de gebruiker geen 2 euro munt kan gebruiken. Nu is de maximale consumptieprijs momenteel 1 euro, maar dat kan natuurlijk ooit verhoogd worden. Alternatief is:


2 euro: 20 pulsen
1 euro: 10 pulsen
50 cent: 5 pulsen
20 cent: 2 pulsen


Ik denk dat ik maar het eerste schema aanhoudt (en ik wou dat ik een muntautomaat voor zes munten gekocht had).


Ik wil het zo maken dat er een vier digit display komt waarop je ziet hoeveel cent er is ingeworpen. Je kunt dan op een startknop drukken en dan gaat Zyptar iets doen.


Het programmeren van de muntautomaat gaat door op wat knopjes te drukken en de vier munten er elk 25 keer in te gooien. Het apparaat slaat de karakteristieken van de munt op. Op youtube staat een video die dit uitlegt.






Het apparaat heeft twee data-aansluitingen waarvan ik er één gebruik, namelijk de grijze draad die de pulsen geeft. De grijze draad heb ik in pin 2 van de Arduino Mega gestoken.


Ik heb een testprogrammaatje geschreven dat de werking aantoont:


const byte interruptPin = 2;
volatile int pulseCount = 0;

void setup() {

  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt (digitalPinToInterrupt(interruptPin), countPulse, RISING);
  Serial.begin(9600);
  Serial.println("Coin Acceptor ready");
  pulseCount = 0;
}


void loop() {
  // put your main code here, to run repeatedly:
Serial.println(pulseCount);
delay (1000);
}
void countPulse(){
  pulseCount += 1;
  }


Het koste nog wat gepuzzel om dit voor elkaar te krijgen. Het is bijvoorbeeld echt nodig om de interruptpin als INPUT_PULLUP te definiëren. Als je dat niet doet dan is er geen weerstandje dat de spanning op de pin omhoog trekt en dat betekent dat de spanning op de pin een beetje staat te variëren en de pin dus heel veel niet bedoelde interrupts genereert.


Ook is het nodig om digitalPinToInterrupt te gruiken omdat de pinnummers niet gelijk zijn aan de interruptnummers en per board verschilt dit ook nog.


Wat het programmaatje doet is een parameter pulseCount bijhouden die weergeeft hoeveel pulsen er langsgekomen zijn.


Wanneer pin 2 hoog wordt (er komt een pulse aan), dan wordt countPulse() aangeroepen en die verhoogt pulseCount  met 1. In de onderstaande video zie je wat er gebeurt wanneer ik een euro in de gleuf gooi. Op het scherm zie je de waarde van pulseCount.




Nou, weer een stukje Zyptar dat ik onder de knie heb.

Subsystemen voor Zyptar: De bonnenprinter

Er rollen steeds meer onderdelen voor het Zyptar-project binnen. Ik ben nu bezig om alle deelsystemen aan de praat te krijgen.


Eén van die deelsystemen is een een bonnenprinter die een kaartje uitprint met een toekomstvoorspelling of horoscoop (of iets anders).


Ik heb de printer aan de Arduino Mega gekoppeld. De Arduino zit weer met een USB-kabel aan de computer. Hiermee kan ik een programma laden.


Zoals je ziet, zit er ook nog een labvoeding bij. Normaal voedt je de Arduino met de USB-kabel, maar deze printer trekt 1,5 Ampere (het is een thermische printer) en dat haalt USB niet.


Proefopstelling
Gisteravond lukt het me maar niet om de printer aan de praat te krijgen. Hij pruttelde een beetje maar er kwam geen print uit. En dat kwam dus omdat ik er een voeding van 0,8 Ampere aan had gehangen. Te weinig.... De labvoeding levert gelukkig 3 Ampere. Betekent wel dat ik nog een dikke voeding aan moet schaffen.


De printer heeft een seriële besturing, dit betekent dat hij aangesloten wordt met twee draadje, een zend-draad en een ontvangst-draad. Deze gaan naar twee digitale pinnen van de Arduino.


Nu heeft deze Arduino vier hardwarematige seriële poorten: Serial (de USB-aansluiting), Serial1, Serial2 en Serial3. Maar je kunt ook twee digitale pinnen van de Arduino softwarematig een seriële poort laten zijn. Ik kwam er achter dat je daar niet alle pinnen voor kunt gebruiken, want de lees-pin moet interrupts ondersteunen. Een interrupt betekent dat de processor een signaal krijgt wanneer de pin van spanning verandert. Je kunt alleen digitale pinnen 10, 11, 12, 13, 14, 15, 50, 51, 52 en 53 gebruiken (plus een aantal analoge pinnen).


Ik heb de printer aangesloten op Serial1, wat de pinnen 18 (TX) en 19 (RX) gebruikt. De T(ransmit) van de Arduino sluit je aan op de R(ead) van de printer en andersom. Ik hoef dan geen pinnen te specificeren, want die liggen hardwarematig vast.


Er is een demoprogrammaatje te downloaden om de printer te testen.



int heatTime = 80;
int heatInterval = 2;
char printDensity = 15;
char printBreakTime = 15;

void setup()
{
 Serial1.begin(19200); // to write to our new printer
}


void loop(){
 initPrinter();
 Serial1.println("Hallo Welt...");
 Serial1.write(10); //Sends the LF to the printer, advances the paper
 Serial1.write(10);
 Serial1.write(10);
 do { } while (1>0); // do nothing
}

void initPrinter()
{
 //Modify the print speed and heat
 Serial1.write(27);
 Serial1.write(55);
 Serial1.write(7); //Default 64 dots = 8*('7'+1)
 Serial1.write(heatTime); //Default 80 or 800us
 Serial1.write(heatInterval); //Default 2 or 20us
 //Modify the print density and timeout
 Serial1.write(18);
 Serial1.write(35);
 int printSetting = (printDensity<<4) | printBreakTime;
 Serial1.write(printSetting); //Combination of printDensity and printBreakTime
}


Kennelijk door een Duitser geschreven....


Resultaat
En ja hoor nu werkt de printer OK. In principe kan deze printer ook plaatjes en barcodes printen. Maar dat vergt wel wat meer programmeerkunst. Mogelijk ga ik dat wel doen om het kaartje er wat interessanter uit te laten zien. Maar dat is voor later. Ik weet nu dat ik printer kan laten werken, dus ik kan hem veilig inbouwen.


Het enige wat ik nog met deze printer moet doen is hem wat meer in "Zyptar-stijl" brengen. Dus een beetje meer versierd. Of moet ik zeggen protseriger? Het is wat lastig om hem goud te spuiten maar ik kan er wel een gouden lijstwerkje omheen maken.