Category Archives: One Two

B4X: An experiment for practical use of IoT on the shop floor

Beacons

At OneTwo, we are always searching for ways to make things easier on the workfloor.  For nearly a decade, we introduced barcode scanners everywhere! From architects and accountants, over carpenters and contractors, to farmers and gardeners are now using our small barcode scanners to record times, jobs and used materials.

The last couple of weeks, I’ve been investigating how we could tackle another common issue, but now on the factory shop floor.  Working on a specific step in the development of a product demands the constant focus of the operator so using a barcode scanner to get the instructions is, well, just not practical if you have your hands full.

Time to get to the lab! Provided with heaps of coffee, some unhealthy snacks and an open mind we started putting some ideas together on the whiteboard.  We wanted to give as much feedback to the operator as possible using monitors,  beamer projections at the workstation and personal instructions on phones and tablets.

The key to deliver hyper-contextual content to the users is knowing the location of every chess piece in the game: the workstation, the machine that is going to be build and the operator(s).  The underlying communication technology was going to be Bluetooth Low Energy (BLE). The Raspberry Pi has it and so does almost any phone or tablet. By attaching a cheap BLE Beacon to the machine we could understand the location of all the players.

Using B4X for this project was a no-brainer, as Erels toolbox is just made to build stuff like this! One important link in the chain was missing:  the BLE reader in B4J for the Raspberry Pi.  However, writing some small scripts and calling it using jShell and a couple of timers did the job just fine.

Scripts code:

Two scripts to discover BLE devices around the Raspberry Pi.  Each one runs in its own jShell in B4J. First one scans for devices, second one reads whatever they broadcast.

#!/bin/bash
# Beacon Scan by Alain Bailleul 2017
sudo timeout -s SIGINT 5s hcitool lescan

#!/bin/bash
# Beacon Scan by Alain Bailleul 2017
sudo timeout -s SIGINT 5s hcidump -X > scan.txt

Also, as the Raspberry Pi has to be a BLE beacon itself (so the Android Native app can discover it), I had to write another little script:

#!/bin/bash
# Beacon Scan by Alain Bailleul 2017

sudo hciconfig hci0 leadv 3
sudo hcitool -i hci0 cmd 0x08 0x0008 19 02 01 06 03 03 aa fe 11 16 aa fe 10 00 02 6f 6e 65 2d 74 77 6f 07 $1 $2 $3 00 00 00 00 00 00
sudo hciconfig

IPN=$(ip addr show eth0 | awk ‘/inet / {print $2}’ | cut -d/ -f 1)
IPW=$(ip addr show wlan0 | awk ‘/inet / {print $2}’ | cut -d/ -f 1)
MACN=$(ip link show eth0 | awk ‘/ether/ {print $2}’)
MACW=$(ip link show wlan0 | awk ‘/ether/ {print $2}’)

echo “$MACW;$IPW;$MACN;$IPN;END” > macip.txt

For anything related to presenting the instructions, we could use ABMaterial.

Alright! We’ve got everything we needed to set up a test scenario for a workstation so time to bring out the cool slide:

How it works

Although there are a lot of physical components and different OS’s in play, B4X has all the tools to make them seamlessly talk to each other using one language.  For the native Android part, I wrote my own BLE discovery library based on the altbeacons library. (Note, there is a library available in B4A to discover BLE devices).

For the video demonstration, things you have to keep in mind:

INPUT:

  1. OneTwo box + BLE beacon: represents a machine arriving on the workstation
  2. Raspberry Pi (under the table): represents the workstation
  3. Android Phone: represents an operator/visitor at the workstation

OUTPUT:

  1. On the monitor, for each ‘machine’ some info is presented (e.g. a serial number, to what country it has to be shipped, etc)
  2. On the phone: specific instructions for the operator(s) for this ‘machine’, or a greeting to a visitor.
  3. On the workstation, projected global instructions for the operator(s) for this ‘machine’ with a beamer.

Let’s have a look how all of this plays out:

This turned out to work all very well for a first trial! For real world usage, the project will need some more work (like improving the algorithms to discover the BLE devices, setting thresholds or calculating them without calibration, etc…).  But we are very excited with the possibilities this low-cost solution can already show in such a short time.

Next step will be setting this up on a real workstation on the shop floor in a real factory later this month.

Until next time,

Alwaysbusy

Click here to Donation and get the latest ABMaterial first!

 

 

Advertisements

RealBasic/Xojo: An ADODB Wrapper around the OLEObject framework

Note:
All problems seem to be solved for Xojo, thanks to John Hansen and Paul Lefebvre! Redownload the Wrapper at the end of the article if you had already downloaded it before.

For a project at OneTwo I needed ADODB instead of ODBC to connect to a database. Realbasic/Xojo can do this through the OLEObject, but non of the methods or properties are exposed to the programmer. If you only need it now and then that’s not a real problem, but in some cases you’ll use it all the time. So I decided to write a wrapper around the OLEObjects to make it easier. Also, all available Enums are available (ADOConstants) This way you can just program like this:

BlogArt1a

The code is also much more readable and familiar looking:

  dim CurrentPath as string
  CurrentPath = GetFolderItem("").AbsolutePath
  
  Dim conn as new ADOConnection
  conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + CurrentPath + "Test.mdb"
  
  if conn.Open() then
    MsgBox "Database open!"
  else
    if conn.ErrorsCount > 0 then
      MsgBox str(conn.GetError(0).Number) + "- " + conn.GetError(0).Description
    end if
  end if
  
  dim SQL_str as string
  dim tmp_rs as ADORecordset
  dim ret as Boolean
  
  SQL_str = "INSERT INTO tData ( datText, datValue, datParentID ) SELECT tUren.Uur, 1 AS Expr1, 1 AS Expr2 FROM tUren ORDER BY tUren.Uur;"
  tmp_rs = conn.Execute(SQL_str)
  if tmp_rs <> nil then
    ret = tmp_rs.close
    tmp_rs = nil
    MsgBox "Records added!"
  else
    if conn.ErrorsCount > 0 then
      MsgBox str(conn.GetError(0).Number) + "- " + conn.GetError(0).Description
    end if
  end if
  
  SQL_str = "UPDATE tData SET datValue=datValue+1;"
  tmp_rs = conn.Execute(SQL_str)
  if tmp_rs <> nil then
    ret = tmp_rs.close
    tmp_rs = nil
    MsgBox "Records updated!"
  else
    if conn.ErrorsCount > 0 then
      MsgBox str(conn.GetError(0).Number) + "- " + conn.GetError(0).Description
    end if
  end if
  
  SQL_str = "SELECT datValue FROM tData WHERE datText='12:00';"
  tmp_rs = new ADORecordset
  ret = tmp_rs.Open(SQL_str, conn)
  if ret then
    MsgBox "Selected 12:00 value=" + str(tmp_rs.Field("datValue").IntegerValue)
    ret = tmp_rs.close
    tmp_rs = nil
  else
    if conn.ErrorsCount > 0 then
      MsgBox str(conn.GetError(0).Number) + "- " + conn.GetError(0).Description
    end if
  end if
  
  SQL_str = "DELETE * FROM tData;"
  tmp_rs = conn.Execute(SQL_str)
  if tmp_rs <> nil then
    ret = tmp_rs.close
    tmp_rs = nil
    MsgBox "Records deleted!"
  else
    if conn.ErrorsCount > 0 then
      MsgBox str(conn.GetError(0).Number) + "- " + conn.GetError(0).Description
    end if
  end if
  
  ret = conn.Close
  conn = nil
  
  MsgBox "Done!"

Much more like it! The framework contains the following classes:

BlogArt1b

Note:
You’ll notice that every class contains a inner… OLEObject. This is the real ADODB object, just in case I forgot something 🙂

The fun part is that also objects like Stream are now available in a convenient way. You can program stuff like this with ease:

  dim objStream as new ADOStream()
  dim ret as Boolean
  ret = objStream.Open
  
  ret = objStream.WriteText("Dit is een é text")
  
  objStream.Position = 0
  MsgBox objStream.ReadText + "(" + str(objStream.Size) + ")"
  
  objStream.Position = 0
  objStream.Type = StreamTypeEnum.adTypeBinary
  MsgBox  objStream.Read(2)
  
  ret = objStream.SaveToFile("c:\adodb.txt", SaveOptionsEnum.adSaveCreateOverWrite)
  
  ret = objStream.Close
  objStream = nil

Not all classes have been tested, so if you find an error please report them so I can make the needed changes for everybody.

All classes are open source and can be used for non-commercial and commercial use but you have to include the license.txt file.

Download classes + demo:
ADODBWrapper

Bye for now!


Realbasic/Xojo: An implementation of a help system at One Two

helpsystem
‘Keep it simple’ is our motto at OneTwo. A key element in our thinking process is searching for a way a user can work with complicated software with little to no learning curve. ‘Work’ is the perfect example of this. Our starting point was a real life desktop, with real life folders and documents familiar to the user. At a glance you can see your projects, your employees and the work you’ve done. Installing the software is nothing more than copying a folder. Training of this kind of software takes in most cases a good part of the day (and please RTFM before you call our helpdesk!), but not with ‘Work’.

After a 30 minute training, not computer minded people happily are making rather complicated queries in their database only using pure everyday logic. ‘I want to know who worked yesterday at the Boston site and how long and what material have they used’ is as simple to do in ‘Work’ as dragging the site name from your project map to a WeekView and a familiar looking report will show you exactly what you want. Almost every object can interact with each other and answer everyday questions. The first look on the clients faces when they create a ‘query’ only the ‘IT-Guru-In-The-Cellar’ could do previously makes it all worth.

But software is software. How do you know what you can do with it? That is why even we need a 30 minute training. Not to teach the business logic of the software, but simply explaining to people to use common sense. ‘Don’t think like a computer, think how you would do it in real life’. Show the user what the software can do, with their own familiar data and make this info accessible at any time.

I created a short demonstration of what I mean in the next video (make sure you put it in 1080p mode to see more detail):

This kind of help system adapts itself to the user, and not the other way around. It uses the software and data to create a helpful answer for the non technical user. No need for 2 inch thick manuals, long distance calls to a helpdesk or frustrating searches through IT-logical menus. We have thousands of clients using our software every day and hardly any phone call to our ‘helpdesk’.

Take your time to think about a help system. No mather how intuitive your software is, at some point someone will need help. Make this learning experience as easy as you can. You will also benefit from it, believe me!


12Scan: additional

Some people asked me what the output of 12Scan looks like. Well, it’s a plain TXT file with the matrix in it. A zero if it is not checked, A one if the user checked it. Any other program can then use this data how they want.

Here is the output of the demo:


New project at OneTwo: 12Scan


At OneTwo, I’m working at a new program with the work title 12Scan. It is a tool written in RealBasic to scan a page and analyze its contents.

It needs to be able to ‘read’ a page where people color in preprinted empty circles and return a txt file with a grid that represents the users selections. The picture can be taken with any device like flat scanners, webcams or mobile phone cameras.

Here is an example of such an empty page that could be used to check the attendance in a school:

It turns out it was not that easy to build as it looks. Especially the light and the environment were quite a challenge. With the knowledge I learned by building the augmented reality library for android, I could use some of the same techniques in this program.

A couple of things needed to be done. I wanted to avoid any rotation or deformation of the picture to keep the maximum quality of the picture. That meant manipulating the picture in other ways to find the hand colored points.

After some grey scaling, smoothing, blurring, sharpening and the other usual picture manipulations I’ve got a workable picture. The next function searched the blobs. I’ve used some functions I made in the augmented reality lib and that seems to work very well. Next was finding the square shape of the found blobs so I could create the matrix for all hand colored blobs. This looks very simple for a human, but for a computer it is quite a challenge.

This could be solved using a technique called PointsCloud. It searched for the corners within a ‘cloud of points’. The last part was aligning the hand colored points into the found matrix.

We are very satisfied with our preliminary results. It works very well with different light intensities and even on wrinkled or with coffee smothered pages. Here is a little video that shows our results:

This is done by dirty experimental code so my next task is rewriting it in a nice framework and optimizing the code for speed.

Visit us at http://www.one-two.com to see more of our innovating projects.

Until next time!


Some of my projects at One-Two

I’ll post some of  my projects I made at One-Two (http://www.one-two.com). We make Time, Job and tracking programs. As you will see, I love the Canvas!

They are written in RealBasic as this is our main programming language. I’m not very interested it writing ‘normal’ looking programs. I like designing new experimental interfaces to make it very intuitive to work with the software.

So here they come:

12Time: A program to track the time (by using a time clock)

12Work: A Program to track jobs with an alternative GUI (with handheld scanners)

12School: A program to track a school (reception, classes, meals)


%d bloggers like this: