I'm a beginner in this field. I have developed an android app through which I can control the LED's connected to the GPIO pins of ESP Wi-Fi module. That app is connected to Firebase to save the status of the buttons. Everything works fine.
Now I want to implement the followings:
I want, if I manually switch off the LED by removing the GPIO pin of respective LED, that status "LED OFF" should be updated on my app.
I want to add Fan speed controller
For first bullet point, should I use firebase too?
Please suggest the tutorial and ways I can achieve both.
Number 1:
Reading digital output states on an ESP8266
You cannot read and write the same pin without blinking the light as you alter pinMode on the fly. The easiest way is to connect another GPIO as the cathode of the LED, and set that pin's pinMode to INPUT. you can then digitalRead that input to determine if the LED is present and on (1) or not (0).
That only works well on red low-power LEDs though, since the GPIOs only handle 12ma officially. You'll likely want to use something like NPN transistors to deliver VCC to them, in which case you can connect the input pin to the LED anode via a 5-10k resistor, and the LED cathode to GND.
In terms of pushing that status to the update, you can poll every few hundred ms, checking that each read value one is the same as the last, and sending the change off to sparkfun when found. Store the state in a global and compare to the read.
You can also use an interrupt instead of polling. These are more performant and complicated, so for very low-frequency events like LED status, polling suffices and is arguably easier to code from scratch. Do look into interrupts eventually though, they are powerful on single-threaded devices.
Number 2:
Controlling fan speed with an ESP8266
You need a PWM circuit to control a DC motor's fan speed. There's many relatively simple circuits using mosfets to connect and disconnect the ground of the fan very quickly, thus averaging its used power as a ratio of maximum power. The ratio is set using analogWrite with a pin # and a int from 0 to 1024.
Note that your fan probably won't spin if the written value is less than 350; there's not enough voltage at those low values. Also, i'd recommended boosting the PWM frequency to super-sonic levels using analogWriteFreq(16000); in setup() to avoid fan noise. If you can get a 12v DC 4-wire PC cooling fan, you can actually hook the pwm input line to the control GPIO and not have to wire any circuits.
If your fan runs on AC, it's a lot more complicated and dangerous. The simplest circuits use an IGBT transistor to achieve "PWM" on an AC signal, but triacs+diacs, and random-cross solid state relays work well if you manage your own cross timing. Make sure you handle motor impedance as well. Complicated? you bet.
I have found that it's easer and cheaper to modify an existing and cheap fan controller like this one, de-soldering the large potentiometer and replacing with an LDR. The pot's used as a variable resistor, not a voltage divider, so it's easy to mimic. You can then tape an LED to the LDR, hook the LED to a GPIO output, and then use analogWrite() to control the AC output. Experiment with LED resistor values to maximize precision and linearity, though for a fan, even just three usable levels would be an improvement. The opto-isolation from the ESP to main is a nice feature of this cheap method.
If you have an existing commercial multi-speed fan with a few levels, like a ceiling fan or a box fan, you can replace the fan's switch/knob with relays to mimic a human selecting a switch position. You have to reverse-engineer which wires are "hot or not" under the different selections. It's mains AC, so do be careful doing that...
Related
I made a battery bypass to a LG G4 mobile phone, to measure the direct energy consumption with a power monitor. However, 70-80 seconds into the OS boot-up, the system shuts-down with a message 'Invalid battery'.
I've tried several solutions, such as: setting a precise output voltage as measured on the battery; cleaning the 4 battery pins; tighter pin connection, but no luck.
The only hope I could find is within the android docs - Power/Component Power section:
Fake batteries can provide signals on thermistor or fuel gauge pins that mimic temperature and state of charge readings for a normal system, and may also provide convenient leads for connecting to external power supplies. Alternatively, you can modify the system to ignore the invalid data from the missing battery.
And here is my question: How do I modify the system to ignore the invalid data from the missing battery?
There isn't a reference to any article or clear explanation on how to do this. Could anyone point me in the right direction, please? Am I missing something really straightforward?
I'm writing an BLE application, where need to track if peripherals device is advertising or has stop.
I followed getting peripherals without duplications this and BLE Filtering behaviour of startLeScan() and I completely agree over here.
To make it feasible I kept timer which re-scan for peripherals after certain time (3 sec). But with new device available on market(with 5.0 update), some time re-scan take bit time to find peripherals.
Any suggestion or if anyone have achieved this?
Sounds like you're interested in scanning advertisements rather than connecting to devices. This is the "observer" role in Bluetooth Low Evergy, and corresponds to the "broadcaster" role more commonly known as a Beacon. (Bluetooth Core 4.1 Vol 1 Part A Section 6.2)
Typically you enable passive scanning, looking for ADV_IND packets broadcast by beacons. These may or may not contain a UUID. Alternatively, you can active scan by transmitting SCAN_REQ to which you may receive a SCAN_RSP. Many devices use different advertising content in ADV_IND and SCAN_RSP to increase the amount of information that can be broadcast - you could, for instance, fit a UUID128 into the ADV_IND followed by the Device Name in the SCAN_RSP. (Bluetooth Core 4.1 Vol 2 Part E Section 7.8.10)
Now you need to define "go away" - are you expecting the advertisements to stop or to fade away? You will get a Receive Signal Strength Indication "RSSI" with each advertisement (Bluetooth Core 4.1 Vol 2 Part E Section 7.7.65.2) - this is how iBeacon positioning works and there's plenty of support for beacon receivers in Android.
Alternatively you wait for N seconds for an advertisement that should be transmitted every T seconds where N>2T. The downside of the timed approach is that probably not receiving a beacon isn't the same as definitely receiving a weak beacon; to be sure you need N to be large and that impacts the latency between the broadcaster being switched off or moving out of range and your app detecting it.
One more thing - watch out that Advertising stops if something connects to a Peripheral (if you really are scanning for peripherals) another good reason to monitor RSSI.
First scenario: Bonded Devices
We know that if a bond is made, then most of the commercially available devices send directed advertisements in during re-connection. In situations such as this, according to BLE 4.0 specification, you cannot scan these devices on any BLE sniffer.
Second scenario: Connectable Devices
Peripheral devices are usually in this mode when they are initially in the reset phase. The central sends a connect initiator in response to an advertisement packet. This scenario offers you a lot of flexibility since you can play around with two predominant configuration options to alter connection time. These are: slavelatency on the peripheral and conninterval on the central. Now, I don't know how much effort it's going to take get it working on the Android platform, but if you use the Bluez BLE stack and a configurable peripheral such as a TI Sensor tag, then you can play around with these values.
Third scenario: Beacon devices
Since this is what your question revolves around, according to the BLE architecture, there are no parameters to play with. In this scenario, the central is just a dumb device left at the mercy of when a peripheral chooses to send it's beaconing signal.
Reference:
http://www.amazon.com/Inside-Bluetooth-Communications-Sensing-Library/dp/1608075796/ref=pd_bxgy_14_img_z
http://www.amazon.com/Bluetooth-Low-Energy-Developers-Handbook/dp/013288836X/ref=pd_bxgy_14_img_y
Edit: I forgot, have you tried setting the advertiser to non-connectable? That way you should be able to get duplicate scan results
I am dealing with a similar issue, that is, reliably track the RSSI values of multiple advertising devices over time.
It is sad, the most reliable way i found is not nice, rather dirty and battery consuming. It seems due to the number of android devices that handle BLE differently the most reliable.
I start LE scan, as soon as i get a callback i set a flag to stop and start scan again. That way you work around that DUPLICATE_PACKET filter issue since it resets whenever you start a fresh scan.
The ScanResults i dump into a sqlite db wich i shrink and evaluate once every x seconds.
It should be easy to adapt the shrinking to your use case, i.e. removing entries that are older than X, and then query for existance of a device to find out if you received a ScanResult in the last X seconds. However dont put that X value too low, as you must take into account that you still lose alot of advertisement packets on android LE scan, compared to a BLE scan on i.e. bluez..
Edit:
I can add some information i already found for speeding up the performance on Advertisement discovery. It involves modifying and compiling the bluedroid sources and root access to the device. Easiest would be building a full android yourself, i.e. Cyanogenmod.
When a LE scan is running, the bluetooth module sends the scan sesponse via HCI to the bluedroid stack. There various checks are done until it finally gets handed to the Java onScanResult(...) which is accessed via JNI.
By comparing the log of the hci data sent from the bluetooth module (can be enabled in /etc/bluetooth/bt_stack.conf) with debug output in the bluedroid stack aswell as the Java side i noticed that alot of advertisement packets are discarded, especially in some check. i dont really understand, beside that it has something to do with the bluedroid inquiry database
From the documentation of ScanResult we see that the ScanRecord includes the advertisement data plus the scan response data. So it might be that android blocks the report until it got the scan response data/ until it is clear there is no scan response data. This i could not verify, however a possibility.
As i am only interested in rapid updates on the RSSI of those packets, i simply commented that check out. It seems that way every single packet i get from the bluetooth moduly by hci is handed through to the Java side.
In file btm_ble_gap.c in function BOOLEAN btm_ble_update_inq_result(tINQ_DB_ENT *p_i, UINT8 addr_type, UINT8 evt_type, UINT8 *p)
comment out to_report = FALSE; in the following check starting on line 2265.
/* active scan, always wait until get scan_rsp to report the result */
if ((btm_cb.ble_ctr_cb.inq_var.scan_type == BTM_BLE_SCAN_MODE_ACTI &&
(evt_type == BTM_BLE_CONNECT_EVT || evt_type == BTM_BLE_DISCOVER_EVT)))
{
BTM_TRACE_DEBUG("btm_ble_update_inq_result scan_rsp=false, to_report=false,\
scan_type_active=%d", btm_cb.ble_ctr_cb.inq_var.scan_type);
p_i->scan_rsp = FALSE;
// to_report = FALSE; // to_report is initialized as TRUE, so we basically leave it to report it anyways.
}
else
p_i->scan_rsp = TRUE;
I'm developing an Android application to control my quadcopter from the smartphone: I have a periodic process that sends the data acquired from the touchscreen.
The data in then received from a microcontroller, that generates a PWM command to 4 DC motors, obtaining the duty cycle values with a control loop that exploits the received commands.
Can someone suggest a precise criterion to choose the period of the process on the smartphone? Or it is possibile only a "trial and error" approach, checking the reactivity of the system?
EDIT: I have successfully implemented it just setting the frequency of the smartphone task as 2*control_loop_frequency
If you knew or could measure the impulse response of the system it would be possible to determine an appropriate control loop rate; however you do not have that data and it will be confounded in any case by external factors such as wind speed and direction. Determining the rate empirically will be faster than determining the precise characteristics.
If the control is open-loop, then probably you have to ask yourself how far off the desired course can you allow the vehicle to get before a correction is applied. That will depend on the vehicles maximum speed (in any direction).
In the end however Android is not a real-time operating system, so there are no guarantees that any particular periodic update will be performed precisely; its always going to be somewhat non deterministic. At a guess I would imagine that such a system might manage 10Hz update reasonably reliably and that would probably be sufficient for adequate control and responsiveness - if the only feedback is via the human controller's hand-eye coordination, that is perhaps the limiting factor in the system response.
I've got a problem. I'm developing an android application that scans for wireless accesspoints/routers. I've been testing a couple of devices and I'm getting scan rates of 2, 1, 0.5, 0.1 etc. scans per second.
My goal is to reach 10 scans per second because a router can send beacons 10 times a second. And we need this for our application.
Is there away to make this possible? Perhapse hack a rom and replace the wifi drivers? I've been looking in to this but I can't find anything about this frequentie inside the driver.
The driver used is BCM4329 driver, I can't find any datasheets of the BCM4329 so it's kinda hard to figure this out.
Thanks in advance.
flitjes
I'm not familiar with driver development but I know it's one of the hardest thing in computer science so unless you have good knowledge in linux kernel development I would forget about it.
Moreover, you still need to scan the 12 Wi-fi channels to be sure that you are detecting all access points. An access point broadcasts a beacon every 100ms * 12 channels = 1.2 seconds. Spending less time than that and you risk missing access points.
You don't need to change anything in the device driver, Android makes it available to you to scan for access points. See the documentation.
Although requesting that many scans will probably not be very good for the battery life and the responsiveness of your app...
Your assumption that beacon rate is 10 per second is incorrect. This is really an AP configuration parameter, although 10 per sec is default in most. Besides that, APs do not send beacons simultaneously, if this happens, it's called a collision and a back-off algorithm is used for retransmission. In addition, even scanning 10 times per second doesn't make it certain for you to capture all beacons, like was pointed out in the previous answers.
if u use 4339 driver, you could not set the scan rate in driver or android api which is fixed in 4339 firmware, scan is about all channels && time u spend on each channel, according to the 80211 spec, which is part of mac && phy. in this case u just need to get the beacon, so u should use passive scan and use fixed channel && MaxChannelTime u want.
u have to ask broadcom for speical fw to figure out your problem,
IEEE
Std 802.11-2012 page 978
10.1.4.2 Passive scanning
If the ScanType parameter indicates a passive scan, the STA shall listen to each channel scanned for no
longer than a maximum duration defined by the MaxChannelTime parameter.
I would like to remotely reprogram my Arduino via Android over Bluetooth SPP. The first step is to reset the ATMEGA microcontroller. This is accomplished on the Arduino by toggling the DTR line. Is there any API to control the Bluetooth SPP control lines from the Android environment?
Also it is supported by SPP in general to send or receive the control signals (DTR, DSR, RTS, CTS) I do not know any API or library for android right know, but as you just want to reset your controller...
If it is o.k. for you to change your firmware you can also create your own reset-command that can be received on your UART (over SPP).
If you receive that command you could call something like
asm("jmp 0x3800");
where you have to modify the jmp-address to point to your bootloader.
You also might want to change your interrupt vector to point to your bootloader.
Or enable your watchdog and call
while(1);
This will also automatically change the interrupt vector to the bootloader's interrupt vector and reset all SFRs. - But it is a little bit slower and the bootloader's interrupt vector must be choosen in the Fuse Bits.
I realise that this is not what you wanted, but you could always flash a new bootloader with a longer timeout and manually press the reset button before starting programming.
The new Arduino bootloader (optiboot) fits in 512B (versus the 2K of the old one) so you have extra space available to your projects; has smart boot detection, so it only enters the bootloader when the reset button is pressed; and you can extend the timeout by editing the watchdog timeout value in the source (around line 267 in optiboot.c).
// Set up watchdog to trigger after 500ms (changed to 2s!)
watchdogConfig(WATCHDOG_2S);