Sunday, November 20, 2016

ZVV Fare Zones as a Google Maps layer

ZVV (Zürcher Verkehrsverbund, is a public transport network in the Canton of Zürich. The website is rich with all the brochures and various maps. But unfortunately the fare zone maps they share in PDF are not easy to view on mobile, and even harder when it comes to deciding whether a particular bus stop belongs to one zone or another.

So if you are looking for a Google Maps overlay that will precisely show you all the ZVV Tarifzonen, seek no more: it's right here!

If you want to make your own, here's a small SVG to KML converter that will download the most recent ZVV zone map and convert it into KML, which can then be imported to My Maps: GitHub Gist.

It is very simple, so it does not render zone numbers. Perhaps that's the reason why ZVV refused to provide KML when I offered them to add this feature?

Wednesday, June 1, 2016

Arduino Wire.h and i2c

So I was implementing an i2c slave on the Rover's Arduinoes; the one that could be read from and written to. All Arduinoes are operating in slave mode, the bus master is a Raspberry Pi board.

For this apparently you have to install both onReceive and onRequest handlers; the "write" operation is simply handled by onReceive by receiving the register and immediately after that a new value; the "read" is a bit more complicated, as onReceive receives the register from the wire, and then onRequest that follows needs to send the data.

All that works quite fine until the speed at which Raspberry Pi queries the Arduinoes is skyrocketing to where Wire library apparently gets confused. In practice it is seen as if an Arduino gets stuck sending -1 to whatever request it receives.

It was bothering me for a while until I decided to figure it out yesterday. Since it's hard to debug an onReceive/onRequest handler via a Serial console (merely because doing Serial operations in an interrupt handler is impossible), I had to look through the Arduino libraries code trying to guess what's going on.

After a while I found a set of instructions that looked suspicious. Apparently Wire library is not accepting any more data unless the buffer received from the previous i2c operation is completely read from!

So the solution looked simple to me; on onReceive, just read from the buffer until it's empty, to make sure it's called the next time data arrives. I'm not sure what exactly confuses Arduino so that it receives more data than Raspberry Pi sends, but it's good to clear the buffer as a safety measure in case someone writes more data by accident.

P.S. From the Wire library source code I also learned that the integer argument passed to onReceive is the same thing returned by Wire.available() before any reads are done. That's because they are computed in the same way, and onReceive, which is called from an interrupt handler, is non-interruptible, as any other Arduino interrupt handler.