ESP32 stops everything when interacting with MIT App inventor 2 - android

Making an app right now that interacts with an ESP32 through bluetooth classic. I'm reading the hall sensor and sending a 0 when its value is above 0, and a 1 when below. Now, when I register that 1 in ai2 and some things happen in the app because of it, the ESP32 malfunctions or something. I stop getting readings from the sensor in the serial monitor, and the bluetooth connection stops. It just seems like the whole esp just stops dead in its tracks. I'm also not sending any data to the ESP32, just receiving from it. The esp code is super small, but the app code not so much.
Only way to fix this issue is resetting the esp, which isn't really doable in my usecase. Any way to fix this?
#include "BluetoothSerial.h"
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
void setup() {
Serial.begin(115200);
SerialBT.begin("Sport Spel"); //Bluetooth device name
}
void loop() {
Serial.println(hallRead());
if (SerialBT.available)
{
if (hallRead() < 0)
{
SerialBT.write('1');
}
else
{
SerialBT.write('0');
}
delay(20);
}
}
Image 1 of app code
Image 2
3
4
5
6

The line
if (SerialBT.available)
should be
if (SerialBT.available())
As it's written in your question, you're testing whether the address of the method named available on the SerialBT object is true, which it always will be. You want to actually call that method, so you need to include the parentheses in order to invoke it.

Related

How to send BLE advertisements from Android to Unity on HoloLens v2

I have already successfully used BLE advertising to broadcast information from one android device and receive it on another. Now I want the observer to be a Unity-app running on the HoloLens v2. The HoloLens does not need to connect to the android-device as I am aware that this does not seem to be supported. I am looking for a broadcaster -> observer solution.
As mentioned, I already have the broadcaster written and it works fine with android -> android. Now I have implemented my observer in Unity, largely inspired by this article, and it looks like this:
#if ENABLE_WINMD_SUPPORT
using System;
using Windows.Devices.Bluetooth.Advertisement;
#endif
public class DemoManager : MonoBehaviour
{
[SerializeField] private StatusDisplay statusDisplay;
private void Awake()
{
#if ENABLE_WINMD_SUPPORT
StartWatcher();
#else
statusDisplay.Display("UWP APIs are not supported on this platform!");
#endif
}
#if ENABLE_WINMD_SUPPORT
private void StartWatcher()
{
void OnAdvertisementReceived(object sender, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
statusDisplay.Display("Advertisement received!");
}
try {
BluetoothLEAdvertisementWatcher watcher = new BluetoothLEAdvertisementWatcher();
watcher.AdvertisementFilter.Advertisement.ManufacturerData.Add(GetManufacturerData());
watcher.Received += OnAdvertisementReceived;
watcher.Start();
statusDisplay.Display("Watcher started!");
} catch (Exception e){
statusDisplay.Display($"Watcher could not start! Error: {e.Message}");
}
}
private BluetoothLEManufacturerData GetManufacturerData()
{
var manufacturerData = new BluetoothLEManufacturerData();
manufacturerData.CompanyId = 1234;
return manufacturerData;
}
#endif
}
The StatusDisplay script is used for displaying text in a thread-safe way. The company-id 1234 is also used by the broadcaster.
My app has bluetooth capabilities (enabled both in the Unity-editor and in the built solution)
All looks very promising, but sadly the advertisement never seems to be received, or at the very least I am getting no corresponding status message.
Does anybody have any ide what might be wrong? Does anyone have any experience with this problem?
We tested the Bluetooth.Advertisement API and works well on the HoloLens. I found that you assigned the CompanyId(a 16-bit unsigned integer) property a signed decimal number, but we usually provide a hexadecimal number as a Bluetooth LE company identifier code. Could you double-check this point both in your watcher and publisher? For example, it should look like 0xFFFE. Besides, more information about how to use the Bluetooth Advertisement API to send and receive Bluetooth Low Energy advertisements please see:Bluetooth advertisement sample
The problem was not with the Unity-side. My advertisement was malformed. I tested my advertisements with a observer that I also wrote myself on Android. So I accounted for the incorrect formatting there, but of course, the C# Advertisement-watcher did not.

Android - JNI / NDK - crash with SIGSEV - signal handling not triggered

I have Android native C++ code. However, sometimes when I send app to background and back, it crash with SIGSEGV. I want to debug it using my own signal handling and print stack trace, however, when this error occurs, my signal handling is not triggered at all.
To JNI_OnLoad method, I have added:
struct sigaction sighandler;
memset (&sighandler, '\0', sizeof(sighandler));
sighandler.sa_sigaction = &android_sigaction;
sighandler.sa_flags = SA_SIGINFO;
int watched_signals[] = { SIGABRT, SIGILL, SIGSEGV, SIGINT, SIGKILL };
for(int signal : watched_signals)
{
sigaction(signal, &sighandler, &old_sa[signal]);
}
And I have:
static struct sigaction old_sa[NSIG];
static void android_sigaction(int signal, siginfo_t *siginfo, void *context)
{
MY_LOG("Sending PID: %ld, UID: %ld\n", (long)siginfo->si_pid, (long)siginfo->si_uid);
old_sa[signal].sa_handler(signal);
}
However, android_sigaction is never trigerred for the error, when app goes from background. I have tried to create bug in code (writing outside array bounds), trigger it with button push and the callback is correctly called.
What is going on?
Assuming that you're using Android 5.0+ device, your problem may be caused by ART. It exposes own signal() and sigaction() so it has a chance to steal signal and pass it somewhere else.
For debugging purposes you could try direct syscall:
for(int signal : watched_signals)
{
syscall(_NR_sigaction, signal, &sighandler, &old_sa[signal]);
}
So now your handler goes directly to kernel and ART shouldn't change it.
Of course it is OK only for debugging. If you want to go with this for a prod - you need to develop some logic that will respect previous handler.
P.S. also checking returned value and errno is a good idea as well.

How to Get info about phone calls

I have to develop a mobile application that monitors some info about calls, to limit users of a company to spend too much time with the phone near their ears. After x minutes, it should suggest to use earphones.
1st question: is it possible to monitor data like this? Phonecall time duration, start and end, if it's using earphones, internal or external speaker.. I mean, without using jailbreak or other hackings.
2nd question: is it possible doing this for IOS and Android?
3rt question: Do you know if Ionic has the capability to that?
Thank you.
Answering your questions:
Question1: Yes it's possible on Android. It's not possible on iOS. In Android, you can get call information if the user permits. You don't need to do jailbreaking or something. Whereas in iOS no way you can access call info.
Question2: Hope my first answer itself answers this. i.,e Android-Possible, iOS- not Possible
Question 3: AFAIK ionic framework is providing only basic details of Phone call time duration and contacts framework. You should explore more on Android to find out. Even if you use ionic framework you can't access this info at all on iPhone as native ios only not providing these details, we can't expect this from ionic framework.
For Android:
You can easily get the call history or incoming and outgoing call time.
So it is possible in android.
For iOS:
According to your question you want to limit the current calling time of phone near their ears.
So you also do it in iOS by some smartness.
In iOS 10 a new framework introduces for calling i.e. CallKit.
First, you have to get all contact in your application.
So user should call from your app.
For dialing also add the custom phone dialer.
By Some method of callKit you can do:
Add a call observer
#property ( nonatomic ) CXCallObserver *callObserver;
Initialize the call observer:
(instancetype)init
{
self = [super init];
if (self) {
//Initialize the call observer
_callObserver = [CXCallObserver new];
[_callObserver setDelegate:self queue:dispatch_get_main_queue()];
}
return self;
}
Add the delegate of call kit
#pragma mark - CXCallObserverDelegate
- (void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call{
[self callStateValue:call];
}
#pragma mark - Callkit State
- (void)callStateValue:(CXCall *)call {
NSLog(#"Call UIID: %#", call.UUID);
NSLog(#"hasEnded %#", call.hasEnded? #"YES":#"NO");
NSLog(#"isOutgoing %#", call.isOutgoing? #"YES":#"NO");
NSLog(#"isOnHold %#", call.isOnHold? #"YES":#"NO");
NSLog(#"hasConnected %#", call.hasConnected? #"YES":#"NO");
if (call == nil || call.hasEnded == YES) {
NSLog(#"CXCallState : Disconnected");
[timer1 invalidate];
NSLog(#"%ld",(long)self.duration);
if(self.duration>1)
self.duration=1;
}
if (call.isOutgoing == YES && call.hasConnected == NO) {
}
if (call.isOutgoing == NO && call.hasConnected == NO && call.hasEnded == NO && call != nil) {
self.duration = 0;
NSLog(#"CXCallState : Incoming");
NSLog(#"Call Details: %#",call);
}
if (call.hasConnected == YES && call.hasEnded == NO) {
NSLog(#"CXCallState : Connected");
timer1 = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
self.duration++;
NSLog(#"%ld",(long)self.duration);
}];
}
}
You can get the time duration and also add the condition After x minutes, it should suggest to use earphones.

I am trying to make an application that will make phone calls one after another from the list of number

I am developing an application for my friend who is in sales, this application will make phone calls one after another, as soon as one phone call gets disconnected, it will automatically make call to another number from the list. This list can be read from and xml data source or json or mongodb or even from excel sheet.
This could be an ios app that reads data from an end point and stores them and can initiate the call at any point and it wont stop until all the calls are made.
Next call will be made only after the first call has been finished.
I am thinking about using node based web app using google voice to trigger the chain.
I've no experience with ios / android apis but Im willing to work on that if it's a viable thing on that platform.
Note: what we're trying to avoid is whole process of
looking up the phone number.
touch hangup and then click for another phone number.
It should self trigger the next call as soon as current call gets disconnected.
Also we're trying to avoid any paid services like twillo.
Thanks in advance :)
for IOS, you could use CTCallCenter
self.callCenter = [[CTCallCenter alloc] init];
self.callCenter.callEventHandler = ^(CTCall *call){
if ([call.callState isEqualToString: CTCallStateConnected])
{
//NSLog(#"call stopped");
}
else if ([call.callState isEqualToString: CTCallStateDialing])
{
}
else if ([call.callState isEqualToString: CTCallStateDisconnected])
{
//NSLog(#"call played");
}
else if ([call.callState isEqualToString: CTCallStateIncoming])
{
}
};
Download phone list, loop inside phone list, make a call, listening for CTCallCenter and appdelegate's Event, detect user have finish last call, our app active again, then make the next call.
Or you can try in Demo here !

Check if RS232 response contains malformed chars

I have android platform on one end and arduino on the other, connected via serial. Everything works fine, however in some cases arduino restarts itself and causes a flow of unknown characters while its restarting to the serial.
Here is a serial log while arduino is rebooting:
�z������"&O�Z&���B
���F ���cd�:{����t�>��+������2�~����. ���r���DD���^��.�.B�.��ڮ2t��Z:��,R��A�ڢr��Ckˡ���.-���N^���b�����^���
Question is, how can I check on android end if the response was malformed?
You should probably add some kind of "framing" to your messages. CR/LF isn't enough.
For example, put a special "preamble" at the front, and watch for it on the Android side. Choose something that will not occur in the body ("payload") of the message. And choose something that is very unlikely to occur in the random chars that show up on a reboot, a couple of chars long.
You could also put a CRC at the end. "Fletcher" is easy.
I ended up using simple solution like this:
private String filterData(String receivedStr) {
if (receivedStr.contains(RECV_HEADER) && receivedStr.contains(mReadRules.RECV_END)) {
int header_pos = receivedStr.indexOf(RECV_HEADER);
int crc_pos = receivedStr.indexOf(RECV_END);
return receivedStr.substring(header_pos, crc_pos);
} else {
return null;
}
}
It also extracts message if its wrapped around with malformed data.

Categories

Resources