d2jsp
Log InRegister
d2jsp Forums > Off-Topic > Computers & IT > Programming & Development > Arduino Uno
12Next
Add Reply New Topic New Poll
Member
Posts: 3,666
Joined: Oct 28 2014
Gold: 46.01
Nov 28 2016 07:05pm
Alright, so I got a fun project that I need to do for school/my internship.

I have a line of products; coffee, tea, juice and milk as examples.
If you pick up the tea info about it (flavor, cost, etc..) needs to pop up on a screen.
Same goes for the rest of the products.
It needs to be pretty quick in response time.

The tricky part and my main question is.
The client wants to be able to place the tea on any of the 4 "sensors or something else" and the system needs to recognise it as tea regardless of which location it is on.

What type of sensor could I use for this?

1. Color sensors with a colored sticker on the bottom of the cup?
2. Magnetic field sensors, with magnets of different strengths?
3. My client also said something about programmable chips for exactly this.

They want the cheapest and easiest way to go about doing it.
So if you guys have any ideas feel free to post or pm me.

If you don't quite understand what I'm talking about pm me or post here

Ill also be posting in here as a sort "progress thread" so try and keep the spam/+1s to a minimum :rofl:

Thanks in advance

E/ forgot to mention in the post that I'll be working with Arduino to cut the cost down significantly.

This post was edited by SIKKaudio on Nov 28 2016 07:08pm
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Nov 29 2016 06:26am
The cheapest way would be color sensing.

No one is going to want to use a magnetic cup, and implanting a IC on each up is going to get expensive really fast.

NFC/RFID is another choice which will allow you to add detailed information to each cup if you need something with greater depth of information that specifying a color doesnt provide. Such as incorporating price, cup size, refill tracking, etc.

Bar codes are also really good at this and also would be a way cheaper alternative to NFC/RFID.

This post was edited by AbDuCt on Nov 29 2016 06:27am
Member
Posts: 3,666
Joined: Oct 28 2014
Gold: 46.01
Nov 29 2016 11:21am
I did some digging today and found a rfid tag and a scanner for like 8 euros, ill just have to buy a few extra tags and scanners whereever the products end up being placed.

Most likely will be going this route.
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Nov 29 2016 12:04pm
Still think barcode stickers are the better route.

Cheaper and easier, but products also already have them on the products most of the time so you can keep inventory and bring up information. There are many store kiosks that do this, namely in food stores.
Member
Posts: 3,666
Joined: Oct 28 2014
Gold: 46.01
Dec 1 2016 02:54am
Quote (AbDuCt @ Nov 29 2016 08:04pm)
Still think barcode stickers are the better route.

Cheaper and easier, but products also already have them on the products most of the time so you can keep inventory and bring up information. There are many store kiosks that do this, namely in food stores.


yea but the client wants this, so I have to do what they want.


what would be the best way to go about getting the info to pop up on the screen?
programming the Arduino seems simple enough with the RFID-RC522 reader/writer but what would I use to send the file to the screen?
would I also need a mini pc or are there Arduino compatible components that I can use to send a file to the screen.

The screen has a VGA and HDMI input along with an AV input.


and with barcode readers would you need to place the product in a specific position or can it scan no matter how it is placed

This post was edited by SIKKaudio on Dec 1 2016 03:12am
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Dec 2 2016 07:01am
The barcode would need to be read by the laser, so it would have to be positioned on the bottom of the product in a way that the laser line bisects all the bars in the barcode.

As for outputting files to a screen I am not sure what you are saying. Do you just want to display images? Or interactive touchscreen menus and stuff? I've used the nextion touchscreen in some projects and it works okay. You use a editor on a PC to make touch screen GUIs and then communicate data to/from the screen over serial.

Other than that I don't know. You would have to search which rendering libraries the uno has and what screens they are comparable with. You might have better luck with an epi or something with HDMI already built in and then just create a full screen QT or GTK application to display info/read the RFID.
Member
Posts: 20,928
Joined: Mar 18 2009
Gold: 435,910.13
Dec 30 2016 02:20am
why not try a teensy? smaller, more powerful and similar price
Member
Posts: 3,666
Joined: Oct 28 2014
Gold: 46.01
Jan 10 2017 07:11am
Quote (bakalolo @ Dec 30 2016 10:20am)
why not try a teensy? smaller, more powerful and similar price


IDK what this is, but I'll look into it for future projects.

Quote (AbDuCt @ Dec 2 2016 03:01pm)
The barcode would need to be read by the laser, so it would have to be positioned on the bottom of the product in a way that the laser line bisects all the bars in the barcode.

As for outputting files to a screen I am not sure what you are saying. Do you just want to display images? Or interactive touchscreen menus and stuff? I've used the nextion touchscreen in some projects and it works okay. You use a editor on a PC to make touch screen GUIs and then communicate data to/from the screen over serial.

Other than that I don't know. You would have to search which rendering libraries the uno has and what screens they are comparable with. You might have better luck with an epi or something with HDMI already built in and then just create a full screen QT or GTK application to display info/read the RFID.


We are using a BrightSign 1032 right now as a media player, but it's a bit pricey, I think we will be going the route of adding a raspi in-place of the brightsign player.

I still need to reverse the code a bit so instead of playing the video if you scan the tag, that it plays when you remove the tag.
This is what I have so far, and it works perfect except for the end where it needs to activate when I remove the tag not place the tag.
E/ could it be as simple as flipping the HIGH and LOW around?
E2/ switching HIGH and LOW around would work but I would need to replace the delay with something else, some sort of trigger mechanism instead of the timer

Code
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN 9
#define SS_PIN 10

MFRC522 mfrc522(SS_PIN, RST_PIN);

int koffiePin = 2;
int theePin = 3;

String read_rfid;
String ok_rfid_1="46e6868d"; //koffie
String ok_rfid_2="5aadebb"; //koffie2
String ok_rfid_3="46528b8d"; //thee
String ok_rfid_4="ea35fbb"; //thee2



/**
* Initialize
*/
void setup() {
Serial.begin(9600); //9600 = speed
while (!Serial);
SPI.begin();
mfrc522.PCD_Init();
pinMode(koffiePin, OUTPUT);
pinMode(theePin, OUTPUT);
}

void dump_byte_array(byte *buffer, byte bufferSize) {
read_rfid="";
for (byte i = 0; i < bufferSize; i++) {
read_rfid=read_rfid + String(buffer[i], HEX);
}
}


void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
return;

// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial ())
return;

dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println(read_rfid);
if (read_rfid==ok_rfid_1) {
digitalWrite(koffiePin, HIGH);
delay(1000);
digitalWrite(koffiePin, LOW);
}
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println(read_rfid);
if (read_rfid==ok_rfid_2) {
digitalWrite(koffiePin, HIGH);
delay(1000);
digitalWrite(koffiePin, LOW);
}
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println(read_rfid);
if (read_rfid==ok_rfid_3) {
digitalWrite(theePin, HIGH);
delay(1000);
digitalWrite(theePin, LOW);
}
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println(read_rfid);
if (read_rfid==ok_rfid_4) {
digitalWrite(theePin, HIGH);
delay(1000);
digitalWrite(theePin, LOW);
}
}


This post was edited by SIKKaudio on Jan 10 2017 07:31am
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Jan 10 2017 08:07pm
Quote (SIKKaudio @ Jan 10 2017 09:11am)
IDK what this is, but I'll look into it for future projects.


Don't worry about it, he was just trying to seem smart by suggesting something useless. A teensy is just a Uno but smaller form factor using a attiny microcontroller. Provides all the same functionality and more limited feature set.

Quote
We are using a BrightSign 1032 right now as a media player, but it's a bit pricey, I think we will be going the route of adding a raspi in-place of the brightsign player.

I still need to reverse the code a bit so instead of playing the video if you scan the tag, that it plays when you remove the tag.
This is what I have so far, and it works perfect except for the end where it needs to activate when I remove the tag not place the tag.
E/ could it be as simple as flipping the HIGH and LOW around?
E2/ switching HIGH and LOW around would work but I would need to replace the delay with something else, some sort of trigger mechanism instead of the timer


If you need to pull the pin high due to protocol then the only way to do it is to reverse the digitalWrite() calls.

I would refactor the code something like this:

Code
#define koffies 2
#define thees 2

String *koffie_rfid[] = { "46e6868d", "5aadebb"};
String *thee_rfid[] = { "46528b8d", "ea35fbb"};

void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
return;

// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial ())
return;

for(int i = 0; i <= koffies; i++) {
if(koffie_rfid[i] == read_rfid) {
digitalWrite(koffiePin, HIGH);
} else {
digitalWrite(koffiePin, LOW);
}
}

for(int i = 0; i <= thees; i++) {
if(thee_rfid[i] == read_rfid) {
digitalWrite(theePin, HIGH);
} else {
digitalWrite(theePin, LOW);
}
}
}


What this should theoretically do is keep setting the pin high while the rfid tag is being read and it matches one of the two ids. Then when the rfid tag is removed it should set it low.

Although this may not work seeing how you return if you can not read the card or if the card is not present. Another possibility would be:

Code
#define koffies 2
#define thees 2

String *koffie_rfid[] = { "46e6868d", "5aadebb"};
String *thee_rfid[] = { "46528b8d", "ea35fbb"};

void loop() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
digitalWrite(koffiePin, LOW);
digitalWrite(theePin, LOW);
return;
}

// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial ()) {
digitalWrite(koffiePin, LOW);
digitalWrite(theePin, LOW);
return;
}

for(int i = 0; i <= koffies; i++) {
if(koffie_rfid[i] == read_rfid) {
digitalWrite(koffiePin, HIGH);
}
}

for(int i = 0; i <= thees; i++) {
if(thee_rfid[i] == read_rfid) {
digitalWrite(theePin, HIGH);
}
}
}


This will set the pin high, and then when the rfid card is removed and can not be read it will reset both pins to low.

There is more ways to refine this such as exporting the two mfrc522 calls to its own function to reset pins:

Code
#define koffies 2
#define thees 2

String *koffie_rfid[] = { "46e6868d", "5aadebb"};
String *thee_rfid[] = { "46528b8d", "ea35fbb"};

bool card_in_place() {
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent()) {
digitalWrite(koffiePin, LOW);
digitalWrite(theePin, LOW);
return false;
}

// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial ()) {
digitalWrite(koffiePin, LOW);
digitalWrite(theePin, LOW);
return false;
}

return true
}

void loop() {

if(!card_in_place)
return;

for(int i = 0; i <= koffies; i++) {
if(koffie_rfid[i] == read_rfid) {
digitalWrite(koffiePin, HIGH);
}
}

for(int i = 0; i <= thees; i++) {
if(thee_rfid[i] == read_rfid) {
digitalWrite(theePin, HIGH);
}
}
}


This segregates the logic a bit into something more manageable that makes some sense.

Hopefully this gives you some ideas. Basically how I would try to solve this is to either use the isnewcardpresent() and readcardserial() calls to reset the pins if they fail, or setup some kind of watch dog interrupt to catch when a card is removed. Using a interrupt would be the best if the library supports it. This way your code can be doing other stuff, and then when the cards are added or removed it will run a specific function you tell the interrupt to use as soon as they are added/removed, and then it will resume running the previous code. It makes life much easier in the long run since the interrupt functions can set the pins you need high/low only when they need to be rather than every iteration of the loop() function.

Edit:: I didnt add some code so I would compare examples and fix them. I think I missed the function that reads the ID from the reader somewhere.

This post was edited by AbDuCt on Jan 10 2017 08:16pm
Member
Posts: 13,425
Joined: Sep 29 2007
Gold: 0.00
Warn: 20%
Jan 10 2017 09:17pm
Another thing I noticed. You are saving your IDs as 8 byte strings. This is okay since it is readable to yourself but it is not the most space efficient when thinking about the microcontroller. If I recall the Uno only has 2048 bytes of space, meaning you can only keep 256 (probably less since the Uno allocates memory for itself) items.

I would instead store the RFID tags as Unsigned Long values which are 4 bytes long. This instantly doubles the number of items you can store to 512.

How this would work is rather storing a tag, for instance "46e6868d" as a 8 byte string, you would store it as the long integer equivalent 1,189,512,845 which is 4 bytes long due to how integers are stored. This will instantly trim 4 bytes off yet yield the same value when converted between bases (base 16 vs base 10). You would need to write two functions though, a stringhex_to_longint() and longint_to_stringhex() function to ease the use of your application, or just use the long ints themselves, either or.

Just a suggestion, there are probably more ways to decrease requirements but this is the easiest.

This post was edited by AbDuCt on Jan 10 2017 09:21pm
Go Back To Programming & Development Topic List
12Next
Add Reply New Topic New Poll