CoreBluetooth Event Backgrounding - no events in iOS 6.0.1 and higher - core-bluetooth

I work with my ble device in event background mode. So i do not specify any special in info.plist for this.
I have a two troubles here:
1) In iOS 5.1.1 events appear without accessory name.
So when events from ble come when application is in the background i see The "" accessory would like to open "MyAppName"
But in
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
i see the name in the peripheral.name property and advertisementData also contains key kCBAdvDataLocalName #"MyDeviceName"
2) In iOS 6.0.1 and higher the events do not come from background never...
I use ti cc2540 stack, and this is my structs for advertise:
// GAP - SCAN RSP data (max size = 31 bytes)
static const uint8 scanRspData[] =
{
// complete name
0x05, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
'O',
'b',
'd',
'2',
// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), // 100ms
HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), // 1s
HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
// Tx power level
0x02, // length of this data
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm
};
static const uint8 advertData[] =
{
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16( RPC_SERVICE_UUID ),
HI_UINT16( RPC_SERVICE_UUID ),
0x05, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
'O', // 'O'
'b', // 'b'
'd', // 'd'
'2' //2
};
What's wrong? Help please

Dude you DO need to specify the background mode in your info.plist.....
Under Required Background Modes, put in "App shares data using CoreBluetooth" or "App communicates using CoreBluetooth"... (or both, depending on what your app functionality requires).
Then you'll be able to receive background events.

Related

Reading LIN frame from slave node in CAPL

I'm trying to read the linFrame sent from a slave LIN node, to identify when a particular bit has changed from from zero to one.
I'm sending a LIN message to a slave servo that commands it to move beyond a physical end-stop.
Once it physically hits the end-stop, its status message will set a single bit from zero to one. That bit identifies when the servo motor has stalled. My goal is to have the CAPL script detect that the motor has stalled.
My command message is sent by my CAPL script using the "output()" function. I'm unsure which function can read the response, but I think I have to send a header for the response message and then read the response frame.
variables
{
linFrame 0x03 ACT_CTRL_MT3 = {msgChannel=1}; // actuator control command
linFrame 0x21 ACT_STA_MT3 = {msgChannel=1}; // actuator status response
mstimer timer1;
}
on key 'c'
{
// command large angular position from servo at node 3
ACT_CTRL_MT3.RTR = 0;
ACT_CTRL_MT3.byte(0)=0x12; // section 4.5.9 of manual
ACT_CTRL_MT3.byte(1)=0xE4;
ACT_CTRL_MT3.byte(2)=0x14;
ACT_CTRL_MT3.byte(3)=0xFE; // max angle
ACT_CTRL_MT3.byte(4)=0xFF; // max angle
ACT_CTRL_MT3.byte(5)=0x00;
ACT_CTRL_MT3.byte(6)=0x00;
ACT_CTRL_MT3.byte(7)=0x40;
output(ACT_CTRL_MT3); // update command payload
// Send the frame header
ACT_CTRL_MT3.RTR = 1;
output(ACT_CTRL_MT3);
settimer(timer1,5000); // wait 5 seconds for motor to move
}
on timer timer1{
//send header of status message
ACT_STA_MT3.RTR = 1;
output(ACT_STA_MT3);
write("Reading message...");
//output message context
writelineex(1,1,"FrameId=%d Length=%d, 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X;", ACT_STA_MT3.ID, ACT_STA_MT3.DLC,
ACT_STA_MT3.byte(0), ACT_STA_MT3.byte(1), ACT_STA_MT3.byte(2), ACT_STA_MT3.byte(3), ACT_STA_MT3.byte(4), ACT_STA_MT3.byte(5), ACT_STA_MT3.byte(6), ACT_STA_MT3.byte(7));
}
The data that is written by the "writelinee" function is very different from the values seen in my LIN trace window in CANalyzer.
I find it especially strange that the ID field written out is different from the ID set in the variables section at the start of the code. In the code I define the frame ID of that status message as 0x21, but the write command gives a different value (0x35 I believe, although I'm away from my setup at the moment.
Unfortunately I do not have CANoe licence so I cannot check my code is functional. I have done similar thinkgs many times, so we should be good.
As I notices from your description you need to do there 3 things:
Send control LIN frame (ID 0x03) with some data to start the motor.
Send status LIN headers (ID 0x21) - remember that LIN Slave cannot initiate transmission on LIN bus so you need to provice LIN headers so LIN Slave can respond with some data.
Get response data from LIN header (data added by LIN slave to LIN header 0x21) - informs about motor stalling.
This is small modification to the code that you provided before. I also marked which things can be done in a different ways (you know CANoe have many features):
variables
{
linFrame 0x03 ACT_CTRL_MT3 = {msgChannel=1}; // actuator control command
linFrame 0x21 ACT_STA_MT3 = {msgChannel=1}; // actuator status response
mstimer timer1;
}
// starts the fun
on key 'c'
{
ACT_CTRL_MT3.RTR = 1; // RTR=1 means that you want to send entire message (header + data)
ACT_CTRL_MT3.byte(0)=0x12;
ACT_CTRL_MT3.byte(1)=0xE4;
ACT_CTRL_MT3.byte(2)=0x14;
ACT_CTRL_MT3.byte(3)=0xFE;
ACT_CTRL_MT3.byte(4)=0xFF;
ACT_CTRL_MT3.byte(5)=0x00;
ACT_CTRL_MT3.byte(6)=0x00;
ACT_CTRL_MT3.byte(7)=0x40;
output(ACT_CTRL_MT3); // this sends the message to the bus
settimer(timer1, 20); // set timer to trigger actions in 20 ms
}
// sending LIN headers (ID 0x21) cyclically
on timer timer1
{
// sends a single LIN header - you can also try to do it this way:
// ACT_STA_MT3.RTR=0;
// output(ACT_STA_MT3);
linTransmitHeader(ACT_STA_MT3); // or linTransmitHeader(0x21);
//set timer again to let LIN Slave respond if stalled later on
settimer(timer1, 20); // reset to execute every 20 ms
}
// event on receiving entire frame (header + response data) from LIN Slave
on linFrame ACT_STA_MT3
{
// not sure where is located your bit that is informing about stalling of the motor, but in this example I assumed it is on first position of byte 0
if (this.byte(0) & 0x01)
{
// you can put some other instructions here
write("Motor has stalled!");
}
// you can also log entire frame (I think your code was fine so I copied it):
writelineex(1,1,"FrameId=%d Length=%d, 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X;", this.ID, this.DLC, this.byte(0), this.byte(1), this.byte(2), this.byte(3), this.byte(4), this.byte(5), this.byte(6), this.byte(7));
}
PS. Try this and let me know if it compiles and works as expected as I literally wrote it in notepad. I will help you to fix potential errors.
About #Maciek answer, it actually works. Interessting to see that if you have your .ldf file in the "ldf explorer" by Vector with the correct signals assigned, then you could replace on linframe <frame> by on signal <any signal>.
The main difference is that linframe receives all the bytes, so you must use masks as #Maciek did here if (this.byte(0) & 0x01) which basically checks the first bit of the first byte. On the other hand, if you had a signal called e.g MyAlarmSignal which was defined in the .ldf file as the first bit of the frame, then you could simply read the signal using on signal MyAlarmSignal and inside the handler use $MyAlarmSignal or simply this to get the value.

Get keyboard type macOS and detect built-in, onscreen or USB

I am developing an application to detect keyboard type for macOS.
I have seen several functions which reading the documentation are supposed to return keyboard id.
However when I test those on my laptop it always print 59.
Can someone tell me where does this 59 value come from and its meaning ??
So far I have tried with oncreen keyboard and built-in keyboard. I have also tried with different layouts but I keep getting that 59
This is my code:
- (CGEventRef)processEvent:(CGEventRef)cgEvent
{
uint32_t kbdType = LMGetKbdType();
NSLog(#"Testing LMGetKbdType ----------> %d", kbdType);
NSEvent* event = [NSEvent eventWithCGEvent:cgEvent];
NSEventType type = [event type];
if(type==NSKeyDown || type==NSKeyUp) {
int64_t val = CGEventGetIntegerValueField(cgEvent, kCGKeyboardEventKeyboardType);
NSLog(#"CGEventGetIntegerValueField: %lld",val);
EventRef ce = (EventRef)[event eventRef];
if(ce) {
unsigned kbt;
GetEventParameter(
ce,
kEventParamKeyboardType,
typeUInt32, NULL,
sizeof kbt, NULL,
& kbt
);
NSLog(#"CARBON Keyboard type: %d",kbt);
}
CGEventSourceRef evSrc = CGEventCreateSourceFromEvent( cgEvent );
if(evSrc) {
unsigned kbt = (NSUInteger) CGEventSourceGetKeyboardType( evSrc );
CFRelease(evSrc);
NSLog(#"COCOA: %d",kbt);
}
}
}
I think these are undocumented values with no external meaning. They are only useful for passing back into other APIs that need a keyboard type (e.g. UCKeyTranslate()).
I think that they are of the same kind that used to be documented in <CoreServices/CarbonCore/Gestalt.h>, under gestaltKeyboardType. However, that header is no longer being updated and doesn't list a type 59.
What exactly are you trying to figure out about the keyboard? If it's general layout, you can use KBGetLayoutType() to learn if it's ANSI, JIS, or ISO. You pass in the keyboard type, like the one you're getting from LMGetKbdType().
The active keyboard layout (e.g. U.S. vs. French vs. Dvorak) should not affect the keyboard type. The keyboard type is an aspect of the hardware and doesn't change as the layout (the interpretation of keys into characters) changes.

Android Wear 2.0 - retrieve calendar color from iOS Apple Calendar

I have an Android Wear app that fetches calendar events via WearableCalendarContract. It works great when paired with Android phones, but I recently discovered a bug when pairing with an iOS device using the Apple Calendar, in that it would not fetch event colors.
After some investigation, it looks to me like the Apple Calendar doesn't let users give individual calendar events different colors - however, it does let them create different calendars, each with their own individual color. Problem is, my WearableCalendarContract query doesn't seem to fetch the calendar colors either.
Is there a solution to this issue, or am I just going to have to set a default color if no color is found?
Code is below. Thanks!
final long currentTime = System.currentTimeMillis();
Uri.Builder builder = WearableCalendarContract.Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, currentTime - DateUtils.DAY_IN_MILLIS);
ContentUris.appendId(builder, currentTime + DateUtils.DAY_IN_MILLIS);
final String[] PROJECTION = {
CalendarContract.Calendars._ID, // 0
CalendarContract.Instances.BEGIN, // 1
CalendarContract.Instances.END, // 2
CalendarContract.Events.EVENT_COLOR, // 3
CalendarContract.Events.TITLE, // 4
CalendarContract.Events.ALL_DAY, // 5
CalendarContract.Events.CALENDAR_COLOR, // 6
CalendarContract.Events.DISPLAY_COLOR // 7
};
final Cursor cursor = getContentResolver()
.query(builder.build(),
PROJECTION,
null, // selection (all)
null, // selection args
null); // order

Arduino keypad matrix example? ( teensyduino )

I'm a beginner using Arduino with a Teensy 3.2 board and programming it as a usb keyboard.
I have two 4 button membrane switches. Their button contacts are on pins 1-8, and the 9th pin holds a soldered together wire of both membrane switches' "ground" line or whatever it's true name is; the line that completes the circuit.
Basically when you press the buttons they are supposed to simply type "a, b, c..." respectively. I've been told I need to use a matrix for this.
I'm looking for an example of how to code a keyboard matrix that effectively supports a one row/9 column line (or vice versa?) I've been unable to find that solution online.
All I have so far is this code which, when the button on the second pin is pressed, sends tons of "AAAAAAAAAAAAAAAA" keystrokes.
void setup() {
// make pin 2 an input and turn on the
// pullup resistor so it goes high unless
// connected to ground:
pinMode(2, INPUT_PULLUP);
Keyboard.begin();
}
void loop() {
//if the button is pressed
if(digitalRead(2)==LOW){
//Send an ASCII 'A',
Keyboard.write(65);
}
}
Would anyone be able to help?
First of all, a 1-row keypad is NOT a matrix. Or better, technically it can be considered a matrix but... A matrix keypad is something like this:
You see? In order to scan this you have to
Pull Row1 to ground, while leaving rows 2-4 floating
Read the values of Col1-4. These are the values of switches 1-4
Pull Row2 to ground, while leaving rows 1 and 3-4 floating
Read the values of Col1-4. These are the values of switches 5-8
And so on, for all the rows
As for the other problem, you are printing an A when the button is held low. What you want to achieve is to print A only on the falling edge of the pin (ideally once per pressure), so
char currValue = digitalRead(2);
if((currValue==LOW) && (oldValue==HIGH))
{
//Send an ASCII 'A',
Keyboard.write(65);
}
oldValue = currValue;
Of course you need to declare oldValue outside the loop function and initialize it to HIGH in the main.
With this code you won't receive tons of 'A's, but however you will see something like 5-10 'A's every time you press the button. Why? Because of the bouncing of the button. That's what debouncing techniques are for!
I suggest you to look at the class Bounce2 to get an easy to use class for your button. IF you prefer some code, I wrote this small code for another question:
#define CHECK_EVERY_MS 20
#define MIN_STABLE_VALS 5
unsigned long previousMillis;
char stableVals;
char buttonPressed;
...
void loop() {
if ((millis() - previousMillis) > CHECK_EVERY_MS)
{
previousMillis += CHECK_EVERY_MS;
if (digitalRead(2) != buttonPressed)
{
stableVals++;
if (stableVals >= MIN_STABLE_VALS)
{
buttonPressed = !buttonPressed;
stableVals = 0;
if (buttonPressed)
{
//Send an ASCII 'A',
Keyboard.write(65);
}
}
}
else
stableVals = 0;
}
}
In this case there is no need to check for the previous value, since the function already has a point reached only when the state changes.
If you have to use this for more buttons, however, you will have to duplicate the whole code (and also to use more stableVals variables). That's why I suggsted you to use the Bounce2 class (it does something like this but, since it is all wrapped inside a class, you won't need to bother about variables).

Does setting exposure/ISO in Google Tango config work?

I am trying to use the Tango device to capture HDR images, but no matter how I set the Tango config ISO and exposure settings, there is no apparent change in the image.
I am disabling the auto-exposure and auto-white balance and setting manual values for the ISO and Exposure time. Regardless of my settings, the colour camera images returned from onFrameAvailable always seem to be in auto mode. The measured average RGB of a given scene is the same, regardless of setting the ISO to 100, 200, 400, or 800, and the exposure to 11.1 ms or 2, 8 or 1/2 times this amount. It seems to still be in auto mode, because I point the device towards a bright window and the window appears pure white for 1 second, then the brightness drops and I can see what is outside the window.
So my Yellowstone tablet is up to date (KOT49H.150731) and I have the Turing release of the client API. I am using the C api with an app that is basically a combination of the example programs for motion tracking, depth, and augmented reality. Is the following code supposed to work?
const bool autoExposure = false;
const int32_t iso = 800;
const double exposure = 11.1*2.0; // milliseconds
if ( TangoConfig_setBool( config_, "config_color_mode_auto", autoExposure) != TANGO_SUCCESS) {
LOGE("config_color_mode_auto Failed");
return false;
}
if ( TangoConfig_setInt32(config_ , "config_color_iso", iso) != TANGO_SUCCESS) {
LOGE("config_color_iso Failed");
return false;
}
if ( TangoConfig_setInt32(config_ , "config_color_exp", (int32_t)::floor(exposure*1e6)) != TANGO_SUCCESS) {
LOGE("config_color_exp Failed");
return false;
}
bool verifyAutoExposureState;
int32_t verifyIso, verifyExp;
TangoConfig_getBool( config_, "config_color_mode_auto", &verifyAutoExposureState );
TangoConfig_getInt32( config_, "config_color_iso", &verifyIso );
TangoConfig_getInt32( config_, "config_color_exp", &verifyExp );
LOGE( "config_colour autoExposure=%s %d %d", verifyAutoExposureState?"On" : "Off", verifyIso, verifyExp );
The reason to use the Tango API for capturing HDR on Android instead of going through the Android API is to get pose estimates along with the images.

Resources