HM-10 CC2541 IBeacon - Sleep issue after random time - sleep

I use HM-10 board (CC2541 inside) with HM-Soft V540 firmware to make IBeacon devices.
But I have a big problem: I configure the HM10 as a beacon, with auto-sleep etc etc, after reset, the HM-10 is sleeping and advertising (2µA when sleep) but after a random time (a few seconds or a few minutes), the HM10 wake up and consume between 15 and 20mA... all the time !! Until I send "AT+RESET" for re-apply the sleeping. (and again, wake up after some seconds...)
This is the commands that I used to set the HM10:
AT+RENEW
AT+RESET
AT
AT+MARJ0x1234
AT+MINO0xFA01
AT+ADVI9
AT+NAMEFAB1
AT+ADTY3
AT+IBEA1
AT+DELO2
AT+PWRM0
AT+RESET
Do you know where is this issue ??
Thanks a lot for your help.

You should change your PWRM0 to PWRM1 worked for me

Guess the problem might be solved for you but as I just run into the same "issue" with the HM-10 (firmware version v549) I wanted to share my solution/finding:
In my case I have figured out that some logger within my code is sending a string of characters via serial extending 80 char. This is actually also the rule that forces the HM-10 to wake up from sleep. So you might use AT+PWRM0 (which enables autosleep) but also make sure that when sending data over serial the string length might not wake up the HM-10 accidentally. Hope this helps a bit.

Related

STM32F407VG Standby mode wake up reason — WUTF flag always set

I’m writing a low power application for the STM32F407VG. It goes into standby mode and can wake up in two ways:
Periodically, using the RTC wakeup timer;
By pressing a push-button connected to the PA0-WKUP pin.
Depending on whether the application was woken up by the RTC or the push-button, I need to perform two different tasks. Therefore, when the firmware resets after waking up from standby mode, I must figure out the wakeup reason (RTC or push-button).
I’ve made the necessary configurations to wake up from Standby mode from either source, and they’re working — the processor does wake up periodically, or when I hit the push-button. The issue is with figuring out the wakeup reason.
The documentation for the RTC_ISR register’s WUTF states the following:
Bit 10 WUTF: Wakeup timer flag
This flag is set by hardware when the wakeup auto-reload counter
reaches 0.
This flag is cleared by software by writing 0.
This flag must be cleared by software at least 1.5 RTCCLK periods before WUTF is
set to 1 again.
This seems perfect to me — if the flag is set, it must be because the wakeup timer reached 0 and woke up the processor.
I inserted some code at the beginning of my firmware to read WUTF and set an LED according to it, and then clear the flag immediately after that. Unfortunately, this flag is always set, not only when waking up from Standby mode due to the RTC, but also when waking up due to the push-button, and even when powering on the circuit for the first time.
I checked the errata sheet for this MCU and found no mention of this issue.
I do realize a workaround would be to read the status of the push-button, and if it corresponds to the pressed state, assume the wakeup reason is due to the push-button being pressed. However, my firmware runs for only a couple of microseconds in Run mode before going back into Standby mode, and due to bouncing issues with the push-button, this kind of detection is not reliable unless I stretch out the Run mode time to several microseconds. This in turn impacts the average power consumption of my application (and therefore battery life). While adding a capacitor might help, I’d like to implement a software-only solution if possible.
It was entirely my bad. I was reading the flag through the following HAL macro:
__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hRTC, RTC_FLAG_WUTF);
It turns out I was using it before initializing hRTC.Instance, so rather than accessing the RTC's registers, it was just reading some random memory (probably address 0). After fixing it, the flag appears to work reliably.

adjusting the baud-rate of pic24

i have a device outputting an data with 19200 baud.
The pic has been configured with SPBRG=12 BRGH=0 start and stop bits have been taken into account.
Nevertheless the pic doesn't receive the correct data!
The data sent has been verified with hyper terminal and oscilloscope.
i can't find the error! Damn
any help?
Thx
Besides the electrical, on some versions of PIC24 (actually I use dsPIC33, but they are much the same) there is also peripheral pin select to deal with. I also set TRIS appropriately, but I think that is not necessary.

Bluetooth RSSI/Inquiry scan on Mac - proximity detection to iPhone without connecting?

I have to dash away from the computer frequently, and I want to trigger some commands to run when my iPhone is close enough/far enough from my iMac (next to it vs. 2-3 metres away/other side of a wall). A couple of minutes latency is fine.
Partial solution: proximity
I've downloaded reduxcomputing-proximity and it works, but this only triggers when the device goes in to/out of range of bluetooth, but my desired range is much smaller.
(Proximity polls [IOBluetoothDevice -remoteNameRequest] to see if the device is in bluetooth range or not.)
Enhancement: rawRSSI
I've used [IOBluetoothDevice -rawRSSI] to get the RSSI when I am connected to the iPhone (when disconnected this just returns +127), but in order to save the battery life of my iPhone I'd rather avoid establishing a full bluetooth connection.
Am I correct in thinking that maintaining a connection will consume more battery life than just polling every couple of minutes?
I've overridden the isInRange method of proximity here to give me a working solution that's probably relatively battery intensive compared to the previous remoteNameRequest: method:
- (BOOL)isInRange {
BluetoothHCIRSSIValue RSSI = 127; /* Valid Range: -127 to +20 */
if (device) {
if (![device isConnected]) {
[device openConnection];
}
if ([device isConnected]) {
RSSI = [device rawRSSI];
[device closeConnection];
}
}
return (RSSI >= -60 && RSSI <= 20);
}
(Proximity uses synchronous calls - if and when I fit it to my needs I will edit it to be asynchronous but for now that's not important.)
Under Linux: l2ping - inquiry scan?
This SO post references getting an RSSI during an 'inquiry scan' which sounds like what I want, but it talks about using the Linux Bluez library, whilst I am on a Mac - I'd rather do it without having to stray too far if possible! (I have considered using a VM with USB pass-thru to hook up a second bluetooth device... But a simpler solution would be preferable!)
I see there is a IOBluetoothDeviceInquiry class, but I am not sure if this is useful to me. I don't intend to learn bluetooth protocol just for this simple problem!
The commands
For interest, and not particularly relevant to the solution, here are the Apple Scripts I currently trigger when
in range:
tell application "Skype"
send command "SET USERSTATUS ONLINE" script name "X"
do shell script "afplay '/System/Library/Sounds/Blow.aiff'"
end tell
out of range:
tell application "Skype"
send command "SET USERSTATUS AWAY" script name "X"
do shell script "afplay '/System/Library/Sounds/Basso.aiff'"
end tell
Though these are likely to get longer!
You are correct that making a connection will cost more energy. However, I'm not aware of APIs on mac OS that will give you access to the RSSI from inquiry scan packets. You could get access to the raw packets from your BT adapter using Mac OS PacketLogger. See this post Bluetooth sniffer - preferably mac osx
You could programmaticly put your device in discovery every couple of minutes, capture the inquiry scan packets with the packetlogger, and parse out the RSSI. You can use WireShark to help you understand how to decode the packets and find RSSI.
Your simplest option is probably to just periodically create a connection, measure RSSI, and then tear down the connection.
In terms of tradeoffs for your use case doing a continuous or periodic inquiry will consume same or even a bit more energy as doing a periodic connect / read RSSI and disconnect. Depending on the use case it sometimes may be more efficient to maintain the connection in a low power mode (sniff with 2.56 sec interval) and remain connected if the device is in range. And use RSSI to monitor proximity (although it is not accurate as interference due to objects change rssi drastically even though the device might be in proximity)

Is it possible to use midiOutLongMsg to play a chord? (Win32 API)

This guys says yes:
http://web.tiscalinet.it/giordy/midi-tech/lowmidi.htm
Same with a really old book from 1998 (Maximum MIDI).
MSDN doesn't mention it.
I'm not getting any sound.
I fill a char buffer with status|note|velocity|status|note|velocity...
Set lpData, dwBufferLength, and dwFlags of a MIDIHDR struct
call midiOutPrepareHeader (MMSYSERR_NOERROR)
call midiOutLongMsg (MMSYSERR_NOERROR)
Still no sound! Spamming midiOutShortMsg is working but will that work for slower machines? Did they change the functionality?
Thanks.
I'm an idiot! I figured it out: Microsoft GS Wavetable Synth does NOT support sending multiple short messages in midiOutLongMsg. The MIDI Mapper DOES!
midiOutShortMsg should be plenty fast, even on slow machines. MIDI interfaces themselves (hardware that is, but some software will limit themselves) run at 31,250 baud. This of course is ignoring any slow code you may have wrapped around where you call midiOutShortMsg.
Anyway, technically you should also be able to get away with one status byte, if the following notes use the same status byte. So, if you want to do note on/off (using velocity 0 for off) and those notes are on the same channel, you could do this:
status|note|velocity|note|velocity|note|velocity|note|velocity
This is called running status.

Handle Events in wxWidgets

I'm creating a game engine using wxWidgets and OpenGL. I'm trying to set up a timer so the game can be updated regularly. I don't want to use wxTimer, because it's probably not accurate enough for what I need. I'm using a while (true) and a wxStopWatch:
while (true) {
stopWatch.Start();
<handle events> // I need a function for this
game->OnUpdate();
game->Refresh();
if (stopWatch.Time() < 1000 / 60)
wxMilliSleep(1000 / 60 - stopWatch.Time());
}
What I need is a function that will handle all the wxWidgets events, because right now my app just freezes.
UPDATE: It doesn't. It's slightly jerky on Windows, and when tested on a Mac, it was extremely jerky. Apparently EVT_IDLE doesn't get called consistently on Windows, and even less on a Mac.
UPDATE2: It actually mostly does. It's fine on a Mac; I misunderstood my Mac tester's reply.
Instead of using a while (true) loop, I'm using EVT_IDLE, and it works perfectly.
UPDATE: It doesn't. It's slightly jerky on Windows, and when tested on a Mac, it was extremely jerky. Apparently EVT_IDLE doesn't get called consistently on Windows, and even less on a Mac.
UPDATE2: It actually mostly does. It's fine on a Mac; I misunderstood my Mac tester's reply.
"ave you requested idle events to be generated at the maximum rate? You have to call RequestMore() on the event, if you don't you will get the next idle event only after some other event has been processed. Note that constant idle processing will cause 100% CPU load on one core."
This works, I have the following code in a graphical window:-
BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
EVT_PAINT (MyCanvas::OnPaint)
EVT_IDLE(MyCanvas::OnIdle)
EVT_MOTION (MyCanvas::OnMouseMove)
END_EVENT_TABLE()
The canvas needs to be updated when my_canvas->Refresh(bClearBackground) is called and not otherwise. To do this I needed to make a modification as the program was eating up half of the cpu time (or 100% of 1 cpu on a duel core).
void MyCanvas::OnIdle(wxIdleEvent &event)
{
wxPaintEvent unused;
OnPaint(unused);
event.RequestMore(false);
}
Setting the parameter of RequestMore() to false makes the app only ask for more when its needed, i.e. only when Refresh() has been called.
Have you requested idle events to be generated at the maximum rate? You have to call RequestMore() on the event, if you don't you will get the next idle event only after some other event has been processed. Note that constant idle processing will cause 100% CPU load on one core.
Even if you request more idle events you can't be sure how long it will take for the next one to arrive. Therefore to get smooth animation you will need to calculate the elapsed time since the last event, and update the display accordingly.

Resources