I am trying to implement the button sample from simplepio. I have made the connection as shown in schematics. After pressing the button I do not get the GPIO callback.
Code I am using is same as that of sample. There are no exceptions only "Starting Activity" gets print in log
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "Starting ButtonActivity");
PeripheralManagerService service = new PeripheralManagerService();
try {
String pinName = BoardDefaults.getGPIOForButton();
mButtonGpio = service.openGpio(pinName);
mButtonGpio.setDirection(Gpio.DIRECTION_IN);
mButtonGpio.setEdgeTriggerType(Gpio.EDGE_FALLING);
mButtonGpio.registerGpioCallback(new GpioCallback() {
#Override
public boolean onGpioEdge(Gpio gpio) {
Log.i(TAG, "GPIO changed, button pressed");
// Return true to continue listening to events
return true;
}
});
} catch (IOException e) {
Log.e(TAG, "Error on PeripheralIO API", e);
}
}
What I have tried so far:
Verified that the circuit and button are functional by running a
python button program in raspbian jessie with following code
#!/usr/bin/env python
import os
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.IN, pull_up_down = GPIO.PUD_UP)
while True:
if (GPIO.input(21) == False):
print("Button Clicked")
sleep(0.1)
The above code prints "Button Clicked" when button is pressed. So I
am sure that the button and GPIO pins on my PI are not an issue.
To make sure there is no issue with logging I also tried
modifying the original program to contain a TextView and a counter
so as when a button is clicked the counter value is incremented and
displayed in TextView but again the callback wasn't received and
TextView wasn't updated.
Tried different edge trigger type but onGpioEdge is never called.
Following is the picture of my setup
Is it just me or is your resistor in the wrong breadboard row
The arrow shows where it is, the circle shows where it should be.
According to the fritzing diagram:
I found the Button driver to be quite unreliable on the Raspberry PI with Android things, after all the driver is pretty much the same code you have.
However, ButtonInputDriver worked flawlessly.
In fact, you do not need to address the GPIO directly and can use the drivers layers, which is simpler. The button driver is here: https://github.com/androidthings/contrib-drivers/tree/master/cap12xx
I suggest you give ButtonInputDriver a try.
It might be possible that I didn't connect the circuit as per schematics or the resistor might not be making good contact. The best way to debug this is as Dave McKelvie suggested is to measure the voltage using voltmeter.
The reason why the Python code was working because the Raspberry PI 3 has internal pull up resistor which was got used as suggested by Dave McKelvie in the comments.
Another reason that the button might not be working is if the GPIO pin is already being used by another application. The logger show the following error for following scenario
Error on PeripheralIO API
com.google.android.things.pio.PioException: android.os.ServiceSpecificException: BCM21 is already in use
at com.google.android.things.pio.GpioImpl.<init>(GpioImpl.java:53)
at com.google.android.things.pio.PeripheralManagerService.openGpio(PeripheralManagerService.java:169)
at com.example.androidthings.simplepio.ButtonActivity.onCreate(ButtonActivity.java:129)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.os.ServiceSpecificException: BCM21 is already in use
at android.os.Parcel.readException(Parcel.java:1697)
at android.os.Parcel.readException(Parcel.java:1636)
at com.google.android.things.pio.IPeripheralManagerClient$Stub$Proxy.OpenGpio(IPeripheralManagerClient.java:776)
at com.google.android.things.pio.GpioImpl.<init>(GpioImpl.java:51)
at com.google.android.things.pio.PeripheralManagerService.openGpio(PeripheralManagerService.java:169)
at com.example.androidthings.simplepio.ButtonActivity.onCreate(ButtonActivity.java:129)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Related
I have a STM32 Nucleo-64 development board with STM32L476RG MCU on it.. I have made a small PCB that, among other things, brings the USB interface to a connector.
I have followed the steps shown here: https://www.youtube.com/watch?v=rLnQ3W8gmjY
When I run the code in debug mode (in STM32CubeIDE v1.10.1) the USB never appears on my computer. I have also probed the USB data +/- signals and see no activity.
When I step through the code, I can see that something is failing immediately in:
MX_USB_DEVICE_Init()
USBD_Init()
The code the that fails is:
USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev,
USBD_DescriptorsTypeDef *pdesc, uint8_t id)
{
USBD_StatusTypeDef ret;
/* Check whether the USB Host handle is valid */
if (pdev == NULL)
{
#if (USBD_DEBUG_LEVEL > 1U)
USBD_ErrLog("Invalid Device handle");
#endif
return USBD_FAIL;
}
The exact line above that fails is if (pdev == NULL)
One thing to note is that the CubeMX tool did NOT add a handler declaration:
USBD_HandleTypeDef hUsbDeviceFS;
...despite me configuring up the USB interface... I added my own line in main.c:
extern USBD_HandleTypeDef hUsbDeviceFS;
..thinking it may be declared elsewhere??
Can someone please help me figure out whats going on?
Thanks!
Followed a video example online, but its not working as expected. I was expecting to see the dev board appear as a USB device on my computer and spit out some text.
As the title suggest I would like to use swo for debugging on an stm32 device without the use of st-link utils.I think I have flashed the code to send messages via swo on my chip but I can not establish a connection with the correct port as some tutorials suggested. I also set the SWV debugger clock rate correctly. I use SWV debugger to check output. The console shows "Download verified successfully", but swv returns nothing. The picture specifics about my configuration:
The SYS configuration shows conflict. I have tried both serial wire and Trace Asynchronous Sw. Is this a reason for the error?
Relative code on my main
while (1)
{
printf("Debug\r\n");
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
#include <stdio.h>
int __io_putchar(uint8_t ch)
{
return ITM_SendChar(ch);
}
Can you please tell me what's the best way to catch a low state (or falling-edge more precisely) of GPIO in an endless script?
To be clear I will run this script at boot (in the bg) and everytime when a user will push a button (connected to this GPIO) this will put this pin at LOW state. I want to detect each one of them and perform actions at every push.
I already have this code but it will consume to much CPU I think... I need sth like an interrupt in my mind :
import RPi.GPIO as GPIO
#Set GPIO numbering scheme to pinnumber
GPIO.setmode(GPIO.BCM)
#setup pin 4 as an input
GPIO.setup(4,GPIO.IN)
# To read the state
While true:
state = GPIO.input(4)
if state:
print('on')
else:
print('off')
EDIT
Here the pinout by BCM or BOARD, I will work with BCM
As you can the the pin number is 4 because my push button is on GPIO4.
Still get off all the time with your code or constant detection of edge event with the code of #jp-jee
EDIT
#!/usr/bin/env python3
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(4,GPIO.IN)
def Callback(channel):
print('pushed')
GPIO.add_event_detect(4, GPIO.FALLING, callback = Callback, bouncetime = 300)
while(True):
time.sleep(1)
Now my code print always pushed when the button is released and print nothing when I push it...
Take a look at the documentation of raspberry-gpio-python.
What you want is GPIO.add_event_detect(channel, GPIO.RISING) in combination with a callback function.
Since you're using a button, you also need to consider bouncing.
In the end, you will end up with something like this (taken from the linked website):
def my_callback(channel):
print('This is a edge event callback function!')
GPIO.add_event_detect(channel, GPIO.FALLING, callback=my_callback, bouncetime=200)
Have you tried to use interrupts?
import time
import RPi.GPIO as GPIO
GPIO.setup(4, GPIO.IN)
def Callback(channel):
state = GPIO.input(channel)
if state:
print('on')
else:
print('off')
GPIO.add_event_detect(4, GPIO.FALLING, callback = Callback, bouncetime = 300)
while(True):
time.sleep(1)
I need to detect when the current playing audio/video is paused. I cannot find anything for 1.0. My app is a bit complex but here is condensed code
/* This function is called when the pipeline changes states. We use it to
* keep track of the current state. */
static void state_changed_cb(GstBus *bus, GstMessage *msg, CustomData *data)
{
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed(msg, &old_state, &new_state, &pending_state);
if(GST_MESSAGE_SRC(msg) == GST_OBJECT(data->playbin))
{
g_print("State set to %s\n", gst_element_state_get_name(new_state));
}
}
gst_init(&wxTheApp->argc, &argv);
m_playbin = gst_element_factory_make("playbin", "playbin");
if(!m_playbin)
{
g_printerr("Not all elements could be created.\n");
exit(1);
}
CustomData* data = new CustomData(xid, m_playbin);
GstBus *bus = gst_element_get_bus(m_playbin);
gst_bus_set_sync_handler(bus, (GstBusSyncHandler) create_window, data, NULL);//here I do video overly stuffs
g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback)state_changed_cb, &data);
What do I do wrong? I cannot find working example on connecting such events on Gstreamer 1.0 and 0.x seems a bit different than 1.0 so the vast exaples there don't help
UPDATE
I have found a way to get signals. I run wxWidgets timer with 500ms time span and each time timer fires I call
GstMessage* msg = gst_bus_pop(m_bus);
if(msg!=NULL)
{
g_print ("New Message -- %s\n", gst_message_type_get_name(msg->type));
}
Now I get a lot of 'state-change' messages. Still I want to know if that message is for Pause or Stop or Play or End of Media (I mean way to differentiate which message is this) so that I can notify the UI.
So while I get signals now, the basic problem, to get specific signals, remains unsolved.
You have to call gst_bus_add_signal_watch() (like in 0.10) to enable emission of the signals. Without that you can only use the other ways to get notified about GstMessages on that bus.
Also just to be sure, you need a running GLib main loop on the default main context for this to work. Otherwise you need to do things a bit different.
For the updated question:
Check the documentation: gst_message_parse_state_changed() can be used to parse the old, new and pending state from the message. This is also still the same as in 0.10. From the application point of view, and conceptionally nothing much has changed really between 0.10 and 1.0
Also you shouldn't do this timeout-waiting as it will block your wxwidget main loop. Easiest solution would be to use a sync bus handler (which you already have) and dispatch all messages from there to some callback on the wxwidget main loop.
I am trying to register to a "Device added/ Device removed" event using WMI. When I say device - I mean something in the lines of a Disk-On-Key or any other device that has files on it which I can access...
I am registering to the event, and the event is raised, but the EventType propery is different from the one I am expecting to see.
The documentation (MSDN) states : 1- config change, 2- Device added, 3-Device removed 4- Docking. For some reason I always get a value of 1.
Any ideas ?
Here's sample code :
public class WMIReceiveEvent
{
public WMIReceiveEvent()
{
try
{
WqlEventQuery query = new WqlEventQuery(
"SELECT * FROM Win32_DeviceChangeEvent");
ManagementEventWatcher watcher = new ManagementEventWatcher(query);
Console.WriteLine("Waiting for an event...");
watcher.EventArrived +=
new EventArrivedEventHandler(
HandleEvent);
// Start listening for events
watcher.Start();
// Do something while waiting for events
System.Threading.Thread.Sleep(10000);
// Stop listening for events
watcher.Stop();
return;
}
catch(ManagementException err)
{
MessageBox.Show("An error occurred while trying to receive an event: " + err.Message);
}
}
private void HandleEvent(object sender,
EventArrivedEventArgs e)
{
Console.WriteLine(e.NewEvent.GetPropertyValue["EventType"]);
}
public static void Main()
{
WMIReceiveEvent receiveEvent = new WMIReceiveEvent();
return;
}
}
Well, I couldn't find the code. Tried on my old RAC account, nothing. Nothing in my old backups. Go figure. But I tried to work out how I did it, and I think this is the correct sequence (I based a lot of it on this article):
Get all drive letters and cache
them.
Wait for the WM_DEVICECHANGE
message, and start a timer with a
timeout of 1 second (this is done to
avoid a lot of spurious
WM_DEVICECHANGE messages that start
as start as soon as you insert the
USB key/other device and only end
when the drive is "settled").
Compare the drive letters with the
old cache and detect the new ones.
Get device information for those.
I know there are other methods, but that proved to be the only one that would work consistently in different versions of windows, and we needed that as my client used the ActiveX control on a webpage that uploaded images from any kind of device you inserted (I think they produced some kind of printing kiosk).
Oh! Yup, I've been through that, but using the raw Windows API calls some time ago, while developing an ActiveX control that detected the insertion of any kind of media. I'll try to unearth the code from my backups and see if I can tell you how I solved it. I'll subscribe to the RSS just in case somebody gets there first.
Well,
u can try win32_logical disk class and bind it to the __Instancecreationevent.
You can easily get the required info
I tried this on my system and I eventually get the right code. It just takes a while. I get a dozen or so events, and one of them is the device connect code.