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.

Arduino-kod
/* * 2015-08-15 * IDE version 1.6.5 * Sketch version 1.0.0 * pc_h * www.pchbutik.se * */ #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.



