PchButik.se

Varuautomat

Varuautomat

Denna sida visar ett experiment med varuautomat, myntinkast och Arduino UNO.


Video: Demonstration av varuautomat och funktion.


Varuautomat bild 1

Varuautomat bild 2

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


Varuautomat bild 3

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.


Varuautomat bild 4

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.


Varuautomat bild 5

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.


Varuautomat bild 6

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


Varuautomat bild 7

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.


Varuautomat bild 8

En polysäkring kan vara bra skydd.


Varuautomat bild 9

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.


Varuautomat bild 10

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


Varuautomat bild 11

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.


Varuautomat bild 12

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.