LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Barcode Scanner

Lots of things wrongnot optimal in that code...

 

Why do you have shift registers that are not used on the left side at all? This only confuses things.

 

Why do you have 4 copies of nearly the same code? What are you going to do when the code needs to be changed? Change it 4 times? That will get old fast. Make a few decent VIs for handling the serial communication, and re-use those VIs. 

 

Don't use bytes at port. The protocol is line feed terminated, so just read a few hundred bytes, and the read will truncate when it encounters the first \n. Bytes at port is terrible, as you can actually read to soon, and then you read not enough bytes, and the next read will get the rest...

 

Why are you using a local to read something, while the terminal is set only 2 cm away from it? Simply ditch the local, and use the wire that sets the terminal.

 

The entire outer sequence structure is redundant. Everything is synchronized by flow anyway. With subVIs, that would be more apparent, as the error wire would simply connect them...

 

The last case returns a Boolean, and it is true in both cases...

 

And so on. It's really hard to get an overview, when the code is so wide and contains so much duplicate code. I'd try to do a few more courses, until you're ready to choose an architecture.

 

 

 

 

 

0 Kudos
Message 11 of 20
(1,796 Views)

The repeated code is for sequencing,probably would have been better as a subVI,but I need the user to first read a code,and if that code isn't what I want it to be I don't want to let him go to the next while loop and so on.

 

The one who taught me the basics of Labview told me to always exit a while loop with a shift register but guess I should ditch that habit.

 

The outer sequence was for something else that was ditched,so i just added some random stuff there don't know why I decided for it to be like that.

 

And as for the local variable it's a habit of mine,I first learned written code in C++ and I like to have the variable at my disposal at any time,as I could always call the value of the local variable anytime when needed.This is a thing of mine to be able to access any data at any time so local variables work really well for me.

 

And the bytes at port was something given to me,the whole visa read/write sequence was given to me with the bytes at port as well.

0 Kudos
Message 12 of 20
(1,793 Views)

@Lopimank wrote:

The repeated code is for sequencing,probably would have been better as a subVI,but I need the user to first read a code,and if that code isn't what I want it to be I don't want to let him go to the next while loop and so on.


Yes, repetitive should be handled by the computer. Either have the same VI 4 times (the 'skip' can be in the VI or not, both are much better then how it is), or refactor to a for loop that does the iteration. That is usually better, especially when the 4 becomes 10, but at 4X repetition is OK-ish.

 


@Lopimank wrote:

The one who taught me the basics of Labview told me to always exit a while loop with a shift register but guess I should ditch that habit.


IMHO, It's silly and confusing. I'd like to hear the reasoning though.

 

I've seen people put a while loop (with a false connected) around everything, even in subVIs, simply because they learned that at an NI course. The course teaches that a top level VI should not depend on the continuous run button... Just to show how good advice can be misinterpreted, or be used out of context...

 


@Lopimank wrote:

The outer sequence was for something else that was ditched,so i just added some random stuff there don't know why I decided for it to be like that.

Less is more. Especially if you can ditch an entire structure... In the perfect VI, there are <10 objects. This is not always practical, main VIs can be a lot bigger, but the less you have, the less bugs you'll have.

 


@Lopimank wrote:

And as for the local variable it's a habit of mine,I first learned written code in C++ and I like to have the variable at my disposal at any time,as I could always call the value of the local variable anytime when needed.This is a thing of mine to be able to access any data at any time so local variables work really well for me.


That figures. In LabVIEW, the use of locals should be kept to a minimum. It's not always avoidable, but in this situation it is.

 

The problem is that because you use the locals, you need the sequence structure! Removing the local, obsoletes the sequence structure.

 


@Lopimank wrote:

And the bytes at port was something given to me,the whole visa read/write sequence was given to me with the bytes at port as well.


Well, you got what you paid for Smiley Wink.

 

IMHO, Bytes at port is a problem waiting to happen. The end character termination is there, and it's much more stable to use.

 

Spoiler
OT: Another benefit of not using BaP, is that you can convert to TCP\IP. Without BaP, that would mean a change of VISA resource, with it, you'll need to refactor. Why change to TCP\IP? for instance, when you need more then 1 bar code scanner. Then you can switch to a moxa TCP\IP to serial converter, and talk to it over TCP\IP. Of course, the drivers will add serial ports to Windows, but what about cRIOs? Without BaP, all your drivers will be ready for this change.

 

Message 13 of 20
(1,787 Views)

Well this is after some cleaning up done,and some restrictions being added.

 

I've removed the shift registers,I removed the outer sequence and made it so it saves the data in MySQL workbench through an UDL link.

 

I still didn't remove the BaP mainly because I can't figure out on how to use termination character right now.The repeated code will be turned into a subVI later,right now I needed this as fast as possible.

 

For now each while loop has a different use scenario,the first one prompts the user to add a rejected product,if he doesn't want to add a rejected product the first while loop will run indefinitely,as I need the same scanner to read other types of code ,more exactly SAP related codes to assign SAP codes to a pallet of batteries.So now it adds the SAP code to the pallet if a normal code is read,otherwise if the "defect" code is read it enters this defect.vi loops.

The second loop is just to read the DMC code written on the battery,this one is really simple.

The third one is for the type of rejection.There's lots and I couldn't figure out how to use multiple scenarios case structure here,so for now I've just added lots of case structure with true or false. 

The forth one is to know which shift was working when the battery was rejected,again didn't know how to use the case structure.

And the fifth one is for confirmation,for example the battery will be saved in the DB if only if he read the confirmation code("confirmare"),and the

other code("refuzare") was to cancel the saving sequence,here I would like to make it so if he reads the "refuzare" code in any of the other loops it just goes back to the beginning.

 

Right now the most important thing for me is to use the multiple scenarios case structure,maybe I need to change the termination character of the scanner or add it to the case structure but didn't have the time to test it out more.

 

This vi can be improved a lot but this is the first thing that came to mind for me,right now it works exactly how I want it to,but will update the vi in the future and send it on this thread when completed.

0 Kudos
Message 14 of 20
(1,753 Views)

I think you attached an older version of your VI.  This one still has shift registers.

 

And oh my god, what you attached is a fragile mess that will never run right.

 

Again, you are abusing local variables when a wire would do.

 

What is up with all those stacked case structures?  You are essentially looking to see if the incoming message is one of a handful of strings, and if it's not, then make it an empty string.  You can easily simplify that.  And it is expandable, much easier to add new strings if necessary.  See below.

 

Defect_BD

Why are you reconfiguring the serial port in every frame?

 

Since you are running a bunch of loops in a sequence for various steps, it sounds like this whole thing should be turned into a "state machine".

Message 15 of 20
(1,741 Views)

@Lopimank wrote:

Well this is after some cleaning up done,and some restrictions being added.

 

I've removed the shift registers,I removed the outer sequence and made it so it saves the data in MySQL workbench through an UDL link.

The sequence structure in the first loop is redundant as well. Flow will force the sequence.

 


@Lopimank wrote:

I still didn't remove the BaP mainly because I can't figure out on how to use termination character right now.


Delete the BaP, and wire a constant to it. For instance, 500 bytes. The read will stop reading when the first \n is encountered. Provided the data is \n terminated of course.

 


@Lopimank wrote:

The repeated code will be turned into a subVI later,right now I needed this as fast as possible.

You could be penny wise, dollar foolish. If you don't mind the expression.

 

You're building a house, with uneven boulders. Make even boulders, then start building. It will be very likely the fastest way to a sound result...

 


@Lopimank wrote:

Right now the most important thing for me is to use the multiple scenarios case structure,maybe I need to change the termination character of the scanner or add it to the case structure but didn't have the time to test it out more.

Those case structures are not the way to do it.

You can simply wire the string directly to the case structure. Then, add all the matching names to one case, make the other default...

 

Or you can make an array constant with all the names that are allowed, and use Search 1D Array to see if there is a match. -1 will mean no, so you can use a Greater Or Equal To 0 or <0 to check. EDIT: Like RavensFan's suggested.

 

Another option would be to create a type def'd enum, and use Scan From String to not only see if there is a match, but also to convert the string to the enum. From there on you wouldn't have to worry about typos anymore, as case structures will adapt to the enum elements.

0 Kudos
Message 16 of 20
(1,735 Views)

I've remade the entire vi,made a subvi for the scanner read,couldn't remove BaP in the sub cause it would give me a timeout error.

 

Thank you everybody for all the help,especially you Wiebe and Raven.

Download All
0 Kudos
Message 17 of 20
(1,711 Views)

@Lopimank wrote:

,couldn't remove BaP in the sub cause it would give me a timeout error.


That's probably because the scanner seems to terminate with a '\r' aka 0x0D, and the current\default termination character is '\n' aka 0x0A. But without toying with the hardware it's hard to say if that's the only change that's needed.

0 Kudos
Message 18 of 20
(1,700 Views)

Well it doesn't matter,I understand BaP isn't very good,but I won't need anything else from this scanner than what you see here.

 

Tank you for all the help and tips you guys gave me!

0 Kudos
Message 19 of 20
(1,697 Views)

Take RavenFans advice and look into a state machine; I'd start with the Simple State Machine once you get the program where you want it and then expand from there. From what I've read in this entire thread, that looks to be exactly what you want.

0 Kudos
Message 20 of 20
(1,681 Views)