Varuautomat
Varuautomat
Denna sida visar ett experiment med varuautomat, myntinkast och Arduino UNO.
Video: Demonstration av varuautomat och funktion.


Varan hindras av utkastaren, eftersom den har samma höjd.

Siffran är pixlig, eftersom det bara är en uppförstorad siffra.
För att det bibliotek som används inte ska ta så mycket minne.

Displayen
Displayen har samma inkoppling i UNO-kortet som i motsvarande experiment.
Myntinkastet
Typen av utsignal ska vara NO (Normal Open).
Det spelar ingen roll vilken pulslängd du använder, eftersom UNO-kortet använder interrupt.
Övriga parametrar på myntinkastet hittar du i manualen.
Några misstag jag gjort: att få i USB-kontakten i UNO-kortet är mycket trångt. Programmera myntinkastet är också trångt.

UNO-kortet får sin ström från Vin-pinnen. Det går bra att ha ström från USB samtidigt som Vin.
Det är en skyddsdiod på UNO-kortet som skyddar din USB från datorn.
Dioden 1N4001 som ligger i serie med signalen är för att skydda UNO-kortet.
Vissa myntinkast har 12 Volt ut med pullup-motstånd och andra har 5 Volt ut.
Om du har ett myntinkast som är på 5 Volt så behövs ingen diod.
Men har du en diod så kan du använda båda typer av myntinkast.

Om lysdioden inte lyser kan den vara felvänd. Det är lättare att vända lysdioden än att byta plats på kablarna.

Räknar upp ett steg för varje puls, så ett för enkrona och fem för en femkrona.
Borde kanske vara av typen icke-nollställningsbart.

En polysäkring kan vara bra skydd.

Strömförsörjning
Myntinkastet ska ha 12 Volt och UNO-kortet klarar max 12 Volt.
Eftersom exemplet har ett blybatteri som kan vara över 12 Volt så passar en step-down bra som stabil spänning under 12 Volt.
En säkring kan också vara på sin plats.
UNO-kortet matas med 12 Volt, och 5 Volt ut från UNO-kortet används för att mata 5 V-enheter.
Tänk på att det är både 12 Volt och 5 Volt på experimentplattan.

2-kanals relä ger ström med 12 Volt till solenoiderna.

Solenoider
Det är viktigt att ha dioder över spolarna i solenoiderna, för att inte störa UNO-kortet.
I bygget på bilderna är det bara en solenoid, och bara en utkastare är byggd.
Hur du vill köra med utkastare för andra får bli ditt eget experiment.

Inköpslista
Video/Embed: Inköpslista del 1.
Video/Embed: Inköpslista del 2.
Arduino-kod
/* * 2015-08-15 * IDE version 1.6.5 * Sketch version 1.0.0 * pc_h * www.pchbutik.se * https://sites.google.com/site/pcharduino2015/myntinkast/varuautomat */ #include <SPI.h> #include <Adafruit_GFX.h> //Detta bibliotek måste vara installerat, eller laddas ner och installeras. #include <TFT_ILI9163C.h> //Detta bibliotek måste vara installerat, eller laddas ner och installeras. //Pinnar till display #define __CS 10 #define __DC 9 //Pinnar till varuautomat #define _SOLENOID_1 A1 #define _SOLENOID_2 A2 #define _BUTTON_1_LED 5 #define _BUTTON_2_LED 7 #define _BUTTON_1_SWITCH 6 #define _BUTTON_2_SWITCH 8 #define _COIN_INSERTED 2 #define _COIN_INSERTED_RESERVED 3 // Reserv om det är två myntinkast. #define _TIMER_SPEED 250 //Används för att skapa hastighet för blinkning och utmatning, 250 millisekunder är 4 per sekund #define _COIN_VALUE 100 //Ett mynt är värt 100 öre alltså 1 krona #define _COST_OF_PRODUCT_1 100 //Vara 1 kostar 100 öre alltså 10 kronor minst #define _EJECTS_OF_PRODUCT_1 4 //Antal som ska matas ut av vara 1, så slutpriset är 0,25 Kr #define _COST_OF_PRODUCT_2 300 //Vara 2 kostar 300 öre alltså 3 kronor minst #define _EJECTS_OF_PRODUCT_2 1 //Antal som ska matas ut av vara 2, så slutpriset är 3 Kr TFT_ILI9163C display = TFT_ILI9163C(__CS, __DC); // volatile int EntererCoinInterrupt = 0; //Antalet inkastade mynt, Denna uppdateras av en interrupt för att inte missa något mynt unsigned long EnterdCoinsValue = 0; //Värdet på instoppade pengar i öre unsigned int Solonoid1Ejects = 0; //Hur många utmatningar som är kvar att göras av vara 1 unsigned int Solonoid2Ejects = 0; //Hur många utmatningar som är kvar att göras av vara 2 boolean Button1LedFlashing = false; //Om knapp för vara 1 ska binka eller inte boolean Button2LedFlashing = false; //Om knapp för vara 2 ska binka eller inte boolean Button1HasBeenUp = true; //Om knapp 1 har varit släppt mellan två kontroller för tryck. boolean Button2HasBeenUp = true; //Om knapp 2 har varit släppt mellan två kontroller för tryck. unsigned long LastLoopTime = 0; //Används för att skapa hastighet för blinkning och utmatning unsigned long LoopSometimer = 0; //Används för att skapa hastighet för blinkning och utmatning // the setup function runs once when you press reset or power the board void setup() { // initialize digital output pins. pinMode(_SOLENOID_1, OUTPUT); pinMode(_SOLENOID_2, OUTPUT); pinMode(_BUTTON_1_LED, OUTPUT); pinMode(_BUTTON_2_LED, OUTPUT); //init output state digitalWrite(_SOLENOID_1, HIGH); digitalWrite(_SOLENOID_2, HIGH); digitalWrite(_BUTTON_1_LED, LOW); digitalWrite(_BUTTON_2_LED, LOW); // initialize digital input pins and med det inbyggda pullup motståndet aktivt. pinMode(_BUTTON_1_SWITCH, INPUT_PULLUP); pinMode(_BUTTON_2_SWITCH, INPUT_PULLUP); pinMode(_COIN_INSERTED, INPUT_PULLUP); //Testa display display.begin(); display.setRotation(1); display.clearScreen(); display.setCursor(0,0); display.print(F("pc_h - Tradera")); LastLoopTime = (millis() & 0xFFFF); //Används för att skapa hastighet för blinkning och utmatning UpdateUI(); attachInterrupt(0, CoinInserted, FALLING); //Denna aktiverar interrupt nummer 0, som är på pinne 2 } // the loop function runs over and over again forever void loop() { //Används för att skapa hastighet för blinkning och utmatning long ThisLoopTime = (millis() & 0xFFFF); if(ThisLoopTime < LastLoopTime){ //Rollover har skett LoopSometimer = LoopSometimer + (0xFFFF - LastLoopTime); LoopSometimer = LoopSometimer + ThisLoopTime; }else{ LoopSometimer = LoopSometimer + (ThisLoopTime - LastLoopTime); } LastLoopTime = ThisLoopTime; if(LoopSometimer > _TIMER_SPEED){ loopSometime(); LoopSometimer = 0; } //Kontrollera knapp 1 if( (digitalRead(_BUTTON_1_SWITCH) == LOW) && (Button1HasBeenUp == true) ){ Button1HasBeenUp = false; if (EnterdCoinsValue >= _COST_OF_PRODUCT_1){ //Kolla att pengarna räcker till denna vara EnterdCoinsValue = EnterdCoinsValue - _COST_OF_PRODUCT_1; //Minska värdet på inlagda pengar med kostnaden av produkt 1 Solonoid1Ejects = Solonoid1Ejects + _EJECTS_OF_PRODUCT_1; //Mata ut rätt antal av vara 1 delay(200); UpdateUI(); } } if(digitalRead(_BUTTON_1_SWITCH) == HIGH){ Button1HasBeenUp = true; } //Kontrollera knapp 2 if( (digitalRead(_BUTTON_2_SWITCH) == LOW) && (Button2HasBeenUp == true) ){ Button2HasBeenUp = false; if (EnterdCoinsValue >= _COST_OF_PRODUCT_2){ //Kolla att pengarna räcker till denna vara EnterdCoinsValue = EnterdCoinsValue - _COST_OF_PRODUCT_2; //Minska värdet på inlagda pengar med kostnaden av produkt 2 Solonoid2Ejects = Solonoid2Ejects + _EJECTS_OF_PRODUCT_2; //Mata ut rätt antal av vara 2 delay(200); UpdateUI(); } } if(digitalRead(_BUTTON_2_SWITCH) == HIGH){ Button2HasBeenUp = true; } } void loopSometime() { //Denna anropas 4 gånger per sekund //Används för att skapa hastighet för blinkning och utmatning //Kolla om det kommit in mynt från interrupt if (EntererCoinInterrupt > 0){ EnterdCoinsValue = EnterdCoinsValue + (EntererCoinInterrupt * _COIN_VALUE); //Räkna upp värdet för inkastade pengar. EntererCoinInterrupt = 0; //Nollställ mynt från interrupt UpdateUI(); //Uppdatera user interface, display och knappar som ska blinka } //Kolla om vara 1 ska matas ut och gör utmatning. if(digitalRead(_SOLENOID_1) == LOW){ digitalWrite(_SOLENOID_1, HIGH); }else if ( (digitalRead(_SOLENOID_1) == HIGH) && Solonoid1Ejects > 0 ){ digitalWrite(_SOLENOID_1, LOW); Solonoid1Ejects --; } //Kolla om vara 2 ska matas ut och gör utmatning. if(digitalRead(_SOLENOID_2) == LOW){ digitalWrite(_SOLENOID_2, HIGH); }else if ( (digitalRead(_SOLENOID_2) == HIGH) && Solonoid2Ejects > 0 ){ digitalWrite(_SOLENOID_2, LOW); Solonoid2Ejects --; } //Kolla om knapp för vara 1 ska blinka och gör blinkning if(Button1LedFlashing == true){ if(digitalRead(_BUTTON_1_LED)){ digitalWrite(_BUTTON_1_LED, LOW); }else{ digitalWrite(_BUTTON_1_LED, HIGH); } } //Kolla om knapp för vara 2 ska blinka och gör blinkning if(Button2LedFlashing == true){ if(digitalRead(_BUTTON_2_LED)){ digitalWrite(_BUTTON_2_LED, LOW); }else{ digitalWrite(_BUTTON_2_LED, HIGH); } } } void UpdateUI(){ //User Interface //Uppdatera display och visa inlagt värde display.clearScreen(); display.setCursor(25,40); display.setTextSize(6); if(EnterdCoinsValue > 999){ display.setCursor(20,40); display.setTextSize(5); } if(EnterdCoinsValue > 9999){ display.setCursor(00,40); display.setTextSize(4); } display.print(EnterdCoinsValue/100); //Uppdatera blinkning och visa om kunden har råd med denna vara 1 if (EnterdCoinsValue >= _COST_OF_PRODUCT_1) { Button1LedFlashing = true; digitalWrite(_BUTTON_1_LED, HIGH); }else{ Button1LedFlashing = false; digitalWrite(_BUTTON_1_LED, LOW); } //Uppdatera blinkning och visa om kunden har råd med denna vara 2 if (EnterdCoinsValue >= _COST_OF_PRODUCT_2) { Button2LedFlashing = true; digitalWrite(_BUTTON_2_LED, HIGH); }else{ Button2LedFlashing = false; digitalWrite(_BUTTON_2_LED, LOW); } } //Interrupt Service Routine(ISR) to call when an interrupt occurs //Efter som det bara kommer pulser från myntinkastet, så måste programmet vara med på noterna. //När det kommer en puls på ingång 2, så avbryts allt program och denna anropas. void CoinInserted(){ //Denna for-loop gör inget annat än knycker 10mS, om det är en 16Mhz processor UNO-kort. for (int i=0; i<2700; i++){ digitalRead(_COIN_INSERTED); } //Kolla att signalen fortfarande är låg efter 10mS if(digitalRead(_COIN_INSERTED) == LOW){ EntererCoinInterrupt++; } }
Denna sida är konverterad med hjälp av AI.
En sida för dig som bygger elektronik själv, experimenterar och laborerar.
Skapad av Per-Anders Hult för PchButik.se.



