howto:thymio:thymio_barcode_reader

Ceci est une ancienne révision du document !


Thymio, barcode reader

I haven't finished writing this yet

#-----
var state = 0
var counter = 0
var deque[2+(1*40)]
var n
var note
var pause
timer.period[0]=500 #half a second

Here I'm setting my variables and the timer.

Technically, deque could've just been set by writing var deque[42], but for better legibility, 2 represents the two items in the deque that are here to count what's in (bad explanation elaborate on that), and “1*40” just says that i can store 40 tuples of 1 item each in the deque.

#-----
onevent button.center
if button.center == 1 then
	state = 1
end
onevent button.forward #skip straight to playing sounds if impatient
if button.forward == 1 and state == 1 then
	state = 3
end

If you've downloaded the code, you'll notice this part is actually at the end. It doesn't matter much, though, it's gonna be read the same way if it's before or after, I just thought it'd be more understandable if I put it at the start for this.

onevent button.center means that on the event that button.center is updated, or in other words, it is pressed, then the following plays. The next three lines set the state variable to 1 when the center button is pressed.

if button.forward == 1 and state == 1, I added this so that it's possible to skip waiting for Thymio to realize that there aren't any more black lines to read. If you can't wait 7 and a half seconds, then here it is.

#-----
onevent timer0
counter++
#--- "white state"
if state == 1 then
call leds.top(0,0,32)
motor.right.target = 25
motor.left.target = 25
	if prox.ground.delta[0] < 700 or prox.ground.delta[1] < 700 then
		call deque.push_back(deque, counter)
		state = 2
		counter = 0
		else if counter > 15 then
			state = 3
		end
	end
end

With the line onevent timer0, I'm telling it to repeat everything that's written underneath every 500ms, or at least until it meets another onevent line. Then, we have counter++, which adds 1 to counter every time it reads it : in this case, that's every 500ms. This is how I count how long something has lasted for.

As stated above, state is equal to 1 when the center button is pressed. So now, thanks to the line if state == 1, it's going to read this part of the code and ignore everything else that only plays when state is equal to anything but 1. I set the top lights to light up in blue, and both motors to move at a speed of 25 each (that's approximately 1 centimeter per second).

if prox.ground.delta[0] < 700 or prox.ground.delta[1] < 700 then if one or the other ground proximity sensors of Thymio's value1) is under 700, then call deque.push_back(deque, counter). This means that the value of counter, at the time of reading this, is put at the end of the deque2). In other words, the time spent from not seeing a black bar to seeing one is placed as a number in the deque so that we can use it later.

state = 2 makes state equal to 2, so when it's done with this whole part and reads the start of the code again, it doesn't play anything that is in if state == 1 then anymore, but instead, it plays what's in if state == 2 then. then, we set counter to 0.

else if counter > 15 then if neither of the proximity sensors are under 700 and the value of counter is above 15 (15*500ms, so 7,5 seconds), then we assume that there's no black bars to read down the line, and we set state to 3

#--- "black state"
if state == 2 then
call leds.top(32,0,0)
if prox.ground.delta[0] > 900 or prox.ground.delta[1] > 900 then 
	call deque.push_back(deque, counter) 
	state = 1 
	counter = 0
end
end
#--- transition, check if empty
if state == 3 then
	call sound.play(-1) 
	call leds.top(0,0,0)
	motor.right.target = 0
	motor.left.target = 0
	call deque.size(deque, n) 
		if n == 0 then
			state = 0
		else
			state = 4
			counter = 0
		end
	call deque.pop_front(deque, (pause/2)) 
end

if state == 2 then it lights the leds up in red. Then, it checks if the ground proximity sensors have a value above 900 this time, in which case we assume it means that it's seeing white. We push the value of counter at the end of the deque again and set state back to 1, so that the previous code can be read again, and it can look for more black lines.

So basically, it's gotta keep repeating those two states until there's no more black lines to read.

After that, we have state 3. As stated above, state is equal to 3 when Thymio hasn't encountered a black line in more than 7,5 seconds. The leds turn off and the motors stop moving.

Then, we have two things that are only relevant later. call sound.play(-1) and call deque.size(deque, n)


1)
prox.ground.delta is, directly quoting the official wiki, the difference between reflected light and ambient light, linked to the distance and to the ground colour. As such, if the ink used for your barcode reflects too much light, then it won't be read correctly. I set the value pretty high but it still happens with a lot of ink, which is why I specified in comments at the start of the code that carbon black ink is preferable.
2)
a deque, or double-ended queue, …
  • howto/thymio/thymio_barcode_reader.1687621284.txt.gz
  • Dernière modification : 2023/06/24 17:41
  • de marie