2017년 6월 6일 화요일

AI2: Bluetooth (BLE): support and documentation


initial impression on the subject.

1. BLE is not in Connectivity, Is there a plan to move it there?
2. What are prospective of documentation and tutorials on BLE?

--
BLE is what is called an AppInventor Extension. It is not available in an AppInventor project by default. You can add the BLE extension by:

2. Download the BluetoothLE.aix file.
3. Click on "Extension" in the AppInventor palette (it should be the last header)
4. Click the link to "Import extension."
5. Upload the .aix file you downloaded in step 2.
6. Confirm the name "BluetoothLE" for the new extension

Once you have done the above steps you will be able to use BLE like any other non-visible component in AppInventor. A summary document with links to BLE tutorials and other resources is available here.

--
BLE is still an experimental implementation. Originally developed as component, but released as extension because it is easer to change things without too many compatibility issues. 
If this becomes more clear, then, who knows, it could be released as a component.

--
When I went to "Controlling Bluetooth Low Energy devices with MIT App Inventor",in "Figure 10: Blocks Used to Get Device Services and Characteristics" was mention there're 4 blocks to get the device's UUIDs,but when I download and import the extension "BluetoothLE.aix" to AI2's palette,these 4 blocks was disappear!Do you know waht's the problem whit it? Thx.

--
These are renamed. The same names, but without the Get in front and using camelcase, i.e. GetCharacteristicsbyIndex becomes CharacteristicsByIndex and so on.

--
But I still don't know how to used them to got those UUIDs,In Fig.10 I couldn't found the example block of the example screen, would you kindly teaching me how to used these blocks to got those UUIDs by AI2?

--
This is still a dark side in the BLE functionality and documentation. I do not know what you intend to do, but quite many of the BLE-sketches seem to use a UART service.
You could test your device for example with this app: https://play.google.com/store/apps/details?id=com.nordicsemi.nrfUARTv2
Or you could try the attached .aia, which allows you to connect to a BLE device and show the supported characteristics and services. if it happens to be UART, it can even read the values and show them.


--
Thank's for your help! I'm trying to study your .aia APP now,hope can understand it's meaning. What I'm going to do is very simply, just used BLE4.0 device as old BT device(not BLE) as a RF UART module. When used the old BT device,after pairing we only need to connected it at APP,but in BLE,we didn't need to paired first,just connected directly with the used of it's address, and when we want to Trx. or Rec. data,we had to assigned there Secvices&Characteristis UUIDs,this part of job is drive me crazy!So I hoped my APP can manage it automatically. After I choice the BLE device from the ListPicker,my APP will found the 2 UUIDS of it and assigned to the BLE's Read or Write block.
   I'd some questions about your .aia APP hope you can explain for me.1'st: I found that you used fixed UUIDs, what kind of BLE is it?when used difference BLE device how to adapt it? 2nd:Can we activated the smartphone's Bluetooth function in our APP?

--
My app allows you to scan for devices and then choose one, but if you already know to which device you want to connect you can skip the selection process.
After you connected, you can check, by pressing the buttons, what the service and characteristic UUID's are that the BLE supports.
You can use this app for many different kind of devices, and if the device uses the UART service, you can read the values it sends out. Many devices like temerature sensors, heart rate meters etc, use this UART service.

I used it for a click switch, that would just send a single number when a button was pressed, and afterwards I used to same app for a device with an accelerometer, that was sending strings like "x=..., y=..., z=...".
Both devices show in the app the data they send. Of course, when you find that you can cummunicate with the BLE device, you must adapt the app to make something meaningful out of it, like showing a graph of values for example.

I do not understand your question about activating the smartphone's Bluetoot function. If you have old BT (not BLE) you must first pair the phone and the device before you can connect to it. With a BLE device, you can scan for devices, as my app does. After starting the scanning process, you can then use the ListPicker button to select a device and connect to it.

--
Thank's for your explanation, now I could found my BLE device's(UART) services & char. UUIDs, but my BLE's UUIDs was difference with your, so I had to change both of them to write or read the data from BLE, and it's what I going to manipulated, I hope my APP can automatically got the UUIDs after I chose the BLE device from the ListPicker.
  In your APP I found that "Disconnect" button seen don't work,but if I change the address parameter to variables"global deviceAddress" will fixed it.About  my question is that when we start our APP,if we didn't activated the Bluetooth interface of smartphone then the APP would not work,so I wander if there had any way in AI2 can forced the smartphone's BT open when we start the APP?

--
Thank you for spotting my mistake with Disconnect! I think it is because I try to disconnect with a string, from the textbox, and probably something is lost in the conversion.
As far finding the UUID's is concerned, that may be not so easy, I have a device that seemingly supports many services and characteristics. So I choose to build a list and find it by name. But in reality there are one very few UUID's that are used, so if you know it for your device, it would be easier to just set it. And I hope that the AI people at MIT will find ways to make this easier, they are certainly working on it!

I am wondering about your question. The trick to find a BLE device is to scan for it, using the call BluetoothLE.StartScanning block, you could do this at initialize if you wish. Do you need to do other things to make the connection happen?

--
I think I'd solved the problem  about that when my APP start running can automatically got the UUIDs after I chose the BLE device from the ListPicker. I'm modified your App to perfomce UART secvice device,in the App can Read/Write data to BLE/UART interface device like HM-10, I would like to shared with you. But there's still a little bug,when the App first connect the BLE device the App can't got the UUIDs,it must connect again! After that the App will work correctly. The attached file is my App,would you like to try and give me some opinions?Maybe you can fixed that bug!


--
I really like your improved design!
As far as the bug is concerned, there are two issues: You do a start scanning twice, but disabling the ListPicker.beforepicking block does not solve the problem.
I think it is maybe a timing issue. You could try to start a clock-timer, when the BLE is connected and do the stuff of finding the UUID's when the timer fires, (also disable the clock again).

Then, finding the UUID's is not as simple as finding the last one in the list as your app seems to think. For my Adafruit that does not work, the UUID's are really different and not the last one in the list. Also, the write UUID characteristic is different from the read UUID characteristic. Further, upper case should not matter, the UUID is a hexadecimal number, but maybe there are device who do this wrong.
See here: https://learn.adafruit.com/introducing-adafruit-ble-bluetooth-low-energy-friend/uart-service.

It is also not a good idea to try and read something immediately after connection in general, because that may not be what you want to do and because of the timing issue I think the UUID's are not available at first.

For my Adafruit I added two listpickers that allows me to make a choice and not to have to type these long numbers. With this I could pick the UUID's and my Adafruit works fine then.
I am out of time now, therefore I attach my .aia with these changes. I hope you can continue with this.


--
As you mention  that it maybe was the time issue that UUID was not available when BLE device been connected,My first thought was also the same. In my experience I feel that BLE device might need some latency or delay time when receive the asking .SupportedServices command,so I add some delay time after the .SupportedServices procedure,when I increase the delay to 2000ms the APP got the SupportedServices data,so I think this way can fixed the problem! Because my BLE module'UUIDs both on the last position so I used that way,If you know your Adafruit BLE's UUIDs position,after received the UUIDs data,you can extract them and assigned them to the variables,so that your APP's user will not need to choose them manually,and this was my original goal!
  The reason that I use the .StartSacnning function in Screen1.Initiallize block is also the same as  when find the UUIDs,if you remove that block you have to touched the ListPicker twice,and even I add a long delay time still can't solved it!do  you have any good ideal can fixed it?

     
--
Sorry for my late reply and I still have to work on solving your problem.
But... did we not tell you to NEVER EVER use a delay in App Inventor???
If you need a delay, you use a clock, otherwise you will have a lot of problems. See also here: The simple Virtual life

--
Thx for your time Ghica,because I was first time joint this forum,so I never hear about the problem of use delay function. Like Joe said that different blocks can never interrupt each other, so I don't how to link the clock as a delay function in the BLE.Connected block, would you kindly give me some hint? Thank's for all!

--
The problem with your ListPicker is that you do the start scanning in the BeforePicking block. This means there is not enough time to scan for devices before the ListPicker is openend and therefore you have to press it twice. You could solve this by starting the scanning in theScreen.Initialize block but the great disadvantage of this is that your device must be turned on before you start the app, something I always forget.
Therefore it is better to have a button to start the scanning. If you want to be fancy, you could enable the clock in the button.Click event block and in the Clock.Timer event block you set the listpicker  elements and open it. If you are not so fancy, there is enough time between pressing the button on clicking on the listpicker and you do not need a clock.

I still have a real problem with the way you determine the characteristic and service to be used. This may work for your device and for the sketch you currently have in your Arduino, but in general it does not work.
If you want a more generalized app, then what you could do is to have listpickers for these,  (you need three, one for read, one for wrtie and one for the service). After a choice is made for the first time you store the values in a TinyDB, and the next time you can retrieve the  values from there. You could also do that for the device address. But it will make your app rather complicated.

In practice, if you are using one of the standard services, it is completely clear what the service UUID should be and the read or write characteristic that go with it. So, when you write your app, you can just hard code it.
In the future there will be functionality in the BLE component that will make this easier for you, but it is not there yet.
I hope you can solve your problems now, otherwise, I am willing to help further.

--
Thx for you help Taifun!

--
Does your problem been solved?After these day of discussion and thinking,I think your problem(me too) about determine the characteristic and service to be used maybe is a fake issue. I don't know what's the purpose of you to used the BLE device? But when you choice the BLE module/type the characteristic and service should be fixed,it will change only when you select another type of BLE that manufactured by difference company,so we can used the fixed characteristic and service UUIDs in our APP. It's also mean that in our APP we don't need to support the function that let user select or input the BLE device's characteristic and service UUIDs! Do you agree with me?
  It's seem that we had the same problem,I was also frequently forget to turned on the BT device before start the app, and that's the reason why I asked you before that this there any way can force to turn the smartphone's Bluetooth interface in AI2! In my example APP if I don't starting the scanning in theScreen.Initialize block just start scanning in the BeforePicking block,even I add a long delay time with it, it's still can't found any BLE device information. By this result I felt that it's might be not because the lack of time.

--
What can I say? I never had a problem, my main problem is that I do not succeed in showing you how to solve your problem.... :-(
I explained why you needed to press the lispicker twice and (together with Taifun) why the delay you still had in your .aia is really bad.
So, here is a little app, which just can connect and disconnect and which uses a clock instead of a delay.
It seems as if there is only one button in it, because the ListPicker is invisible and automatically opened. The Connect and Disconnect buttons are alternatively visible.
Below you can see the blocks. You can copy the blocks in your app via the backpack if you wish.

Then there is the question about the UUID's and how to find or set them. I think you misunderstood the purpose of my app. It is there for educational purposes and if you want to start an app for a new BLE device, to find out what device address it has, what services and characteristics it offers and to allow basic communication with the device.
Once you have found these UUID's, you should modify your code to just have fixed, hard coded UUID's in your app, because the user of your app should never have to deal with these.

Please study the code and I hope that this clarifies things for 
you. 



--
What I can say? Except The Thxs there were still the Thxs! Thxs that you spend so many time to teached me. From you last BLE_connect.aia I 'm clarifies how to fixed my problem,I thing I can carry on my study about the BLE, Thxs again!

--
I am happy to hear that!

--

receive data from another app


Can AI read data sent from another app? I have tried get start value but didn't work.
I'm using Tasker to open my app and send a value as a Data Field, but how do I get my AI app to read it?

--
And Get plain start text Didn't work!

--
see this AI1 example http://puravidaapps.com/snippets1.php#fetchdata how to get data using get plain start text block
the extra key must be APP_INVENTOR_START and in the extra value you can pass your data

--
Unfortunately Tasker doesn't open my app in the same way another AI app would. It will open my app and it will give me the option to send what it calls a data field.
From it's help doc "if data is specified, it is passed to the application when launched. Not all applications examine the data field, however."

--
I've had an other chance to have a poke around Tasker, and found under select action category/Misc there is send intent.
I used the example provided by Taifun to fill in the blanks.

You will have to find the package and class name. You can find how to do that here. http://beta.appinventor.mit.edu/learn/reference/other/activitystarter.html

look for  "Starting Another App Inventor Application from your App Inventor App"

In Tasker
Send Intent


Action
         
Cat
Default

Mine Type

Data

Extra (you put the key and the value separated with a colon)
APP_INVENTOR_START:Helo from tasker
Extra

Package
appinventor.ai_HomerSimpson.HelloPurr

Class
appinventor.ai_HomerSimpson.HelloPurr.Screen1

Target

Activity

If

And in AI
get plain start text will receive the value.


--

Help make taymier off


Help make taymier off .
Hello.
I make an interesting application, but for whatever it worked fine I have to do the off timer .
I have implemented a timer in a separate window and all other windows I made ​​the switch to the timer, but for some reason it does not work !
should work so that when a user visits a page timer and presses the button to turn off after 5 minutes the timer and must disable all application in 5 minutes. But I did so after clicking on the button to turn off after 5 minutes , and the timer window zakryvaetsya user moves from there to come in, and may in this issue?

--
Timers only work in one window. Also, App Inventor applications only work when they are on the foreground, so having a timer for 5 minutes is not reliable.

--
use a timer 10 seconds to prompt empty notifier with no background that will prevent your application from going to "sleep" :) You just have to use home buton  instead of back arrow, the application will run in background at the timers cannot be stopped. Hope it helps

--
example blocks picture


--
thank you so so so much, i can't explain how much. It was vital for my app not to close, as loading again means 60 seconds, so you made my day. Hope it helps other people too, as much as it helped me.
(btw it works even without the notifier block (as in my case it showed a small grey rectangle in the middle of the screen, and without it is perfectly well)

--
Cool solution, Piotr Stępień!
Thanks for sharing!

--
Really really good Thanks, finally I found a solution :)

--

Using the headphone jack as a sensor


Been experimenting with the App Inventor 2 for some time now, building personal projects. 
I'm attempting to create an app that will interact with a piece of hardware-- a set of digital calipers specifically.

I want to utilize the headphone jack as a way to get data from the calipers to the phone, but I can't find a built-in feature or any extensions that achieve this. The data output is very simple, just a clock pin and a data pin, ordinary binary signals, I just need a way to read them.

I know I can use bluetooth, but I wanted to avoid building a separate piece of hardware to accept the data from the calipers and then send over bluetooth. I don't have experience writing my own extensions, which could have been an option but I'm not skilled enough in Java to accomplish this. 

Is there any way this can be done? 

--
What kind of digital calipers have an output port?
A brief search of Amazon found only LCD displays on them.

-- 
They're quite common actually, many don't indicate that beneath a small lid on the upper section of the plastic there is a 4 pin data output port. For example (see last product picture) :

iGaging ABSOLUTE ORIGIN 0-6" Digital Electronic Caliper - IP54 Protection / Extreme Accuracy https://www.amazon.com/dp/B00INL0BTS/ref=cm_sw_r_other_apa_.8ZTyb817BP9D

Only need two or three  of these pins to obtain data through a headphone jack

I have one  working ideas so far- one is to use the MIT sound analyzer extensions source code, adjust its pitch analyzing function to count highs and lows (digital signal), using the clock pin as a trigger for measurement.

But, there must be a protocol already written to read the data from the headphone jack anyways.


--
I see the Amazon PC data cable for that  device costs twice the device itself!

I would consider trying a Raspberry Pi Zero W for $10, if you can find one.
I hear they sold out immediately on Adafruit.

Or just use the Raspberry Pi Zero for $5, and connect to AI2 by Bluetooth.

-- 
Do you have access to technical data on the signalling technique used on the output port?

Is it ASCii serial coding on RS-232 voltages?

An oscilloscope might be necessary to figure out the data stream.

-- 

Fusion Tables (get values from cell)


I need to get a value from a fusion table, e.g. from the cell that is in Column D - Row 2, and use it further (store it into a local variable etc.)

The Pizza Party tutorial doesn't have instructions on how to get info FROM a fusion table and store it to a local variable, it only shows how to display a table in a browser.

Any thoughts?

--
But it looks like it requires some advanced procedures (not the typical AI2 block-like commands)
Is there any tutorial available?

-- 
See this doc for an example of feeding the result of one query into another query...

-- 
Thanks a lot Abraham, I'll check it out.

--

APK Doesn't Work With All Android Phones...


I've finished a project on App Inventor 2 and I've build my APK...

The app works on my device ( Samsung GT-S7390, Android Version: 4.1.2)...but when I install the apk on a Samsung Galaxy S5 with Android 6.0 the app crashes when I change screen (Screen 1 actually works P-E-R-F-E-C-T-L-Y)...

Any suggestions???

--
see the following general tips


2. App Inventor works best if you use images whose size matches the size you want them to appear on your screen. If you import larger images into your app, your app may run out of system memory. Using Images with App Inventor

--
I resized and reposition the images on the screen by doing these two Procedures...

I supposed to have a 1280 x 720 canvas...


-- 
Show us the various Inkscape procedures?

-- 
Actually my "src" folder in .aia archive is larger tha 5mb...It was 8 MB then I cleaned the project and now is 6 MB...

Should this folder be under 5 MB ?


-- 
as explained here Using Images with App Inventor
you should reduce the width and height of the images to the max size you need

-- 
Your Inkscape conversion functions look fishy.

The multiplication by 100 then division by 100 suggests you might be
thinking that AI2 does integer arithmetic and rounds or truncates automatically.

That's not the case.  

Both procedures are just (parameter * (Height/1280))

I vaguely remember seeing reports of fractional px values in
positioning or size settings causing problems.

I suggest wrapping the formula with a floor() or round() to lop off fractional parts.
Also, the *100/100 layers serve no purpose that I can see.

Search YouTube for a video on InkScape in AI2.

App sizes between 5 and 10 MB are marginal.

-- 
I don't understand why my app works on an outdated phone and not on a powerful galaxy S5...

-- 
to find out more about the Runtime Error, you can use Logcat

I normally use Eclipse and Logcat there, but if you have installed the App InventorSoftware (see also Installing and Running the Emulator in AI2), you already have everything you need to use logcat...

How to use Logcat
1. connect your device using USB with your computer
2. in File Manager go to the App Inventor directory, which is  C:\Program Files\App Inventor or similar
3. press Shift and right mouse click the subdirectory commands-for-Appinventor to get the context menu
4. select "open command window here" and you will get a command window of that subdirectory
5. enter adb logcat and the logcat will start running
6. start your app to elicit the error
7. copy the log (see below)

To copy your log, right click, click "select all" and enter to copy the complete log into the clipboard, then open Notepad and paste it using ctrl-v.



--


how to build my app ?


Hi, please help me i'm lost ....
I first did a didact numerical book to learn to read and write.... with audio incrustations, but i realized i can't publish it because of the sounds....
Now i want to transform my book in an app. It is a book of 15 chapter and over 100 pages. In the 100 pages there is alternativly a page of lessons and a page of exercices, and of course a menu for the 15 chapters. 
How can i build it without doing 100 screens (I've tried but arriving to 50 screen impossible to open the emulator). You have to know that the positions of the buttons of the sounds are differents if it's a page of lessons or a page of exercices....
I am totally lost, i've tried to see tutorials but i'm allergic to variables i can't get it ;)
Please help me just to know how much screens i have to do, and what variables, even if my idea is possible.

--
You have to learn how to work with data instead of blocks.


Also see this WheresMit app to see the difference between blocks, screens, and data:

--