pjueon / JetsonGPIO

A C++ library that enables the use of Jetson's GPIOs
MIT License
274 stars 99 forks source link

Trying to run `button_event.cpp` gives error `undefined reference to 'main'` and deletes the file. #38

Closed MotorCityCobra closed 2 years ago

MotorCityCobra commented 2 years ago
$ g++ -o button_event.cpp -lJetsonGPIO -lpthread -I/usr/local/include/Jetso>
/usr/lib/gcc/aarch64-linux-gnu/7/../../../aarch64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
(.text+0x1c): undefined reference to `main'
collect2: error: ld returned 1 exit status
$ dir
button_interrupt.cpp  simple_out.cpp  simple_pwm.cpp  test_all_apis.cpp
pjueon commented 2 years ago

Hmm.. can you retry with $ g++ -o button_event button_event.cpp -lJetsonGPIO -lpthread -I/usr/local/include/JetsonGPIO (Added output program name after -o, and fix the include dir)

I think it's because you skipped the output program name. So g++ thought button_event.cpp is the output file name and there is no source file. It failed to compile and tried to delete the failed compile result(button_event.cpp).

If the file was deleted, pull the repository and try again.

MotorCityCobra commented 2 years ago

Thank you.

That throws no errors and creates a button_event file.

But when I execute the file with ./button_event, I get

$ sudo ./button_event
./button_event: error while loading shared libraries: libJetsonGPIO.so.1: cannot open shared object file: No such file or directory
$ dir
button_event  button_event.cpp  button_interrupt.cpp  simple_out.cpp  simple_pwm.cpp  test_all_apis.cpp
pjueon commented 2 years ago
  1. Did you installed the library and set the user permission according to the instructions?
  2. Can you see libJetsonGPIO.so file in /usr/local/lib?(ls /usr/local/lib to check)
  3. What happens if you run the program without sudo?
MotorCityCobra commented 2 years ago
  1. Did I follow instructions? Yes. I changed the permissions too. I restarted my AGX Xavier after. Should I re-install? (I'll have to figure out how to uninstall a program like this).

  2. $ ls /usr/local/lib
    libJetsonGPIO.so  libJetsonGPIO.so.1  libJetsonGPIO.so.1.0.4  python2.7  python3.6
  3. What happens without sudo? The same result.

pjueon commented 2 years ago
  1. for a quick temporary test:
    try export LD_LIBRARY_PATH=/usr/local/lib/ And run the program again.

  2. Can you share the result

cat /etc/ld.so.conf

and

cat /etc/ld.so.conf.d/libc.conf
MotorCityCobra commented 2 years ago

export LD_LIBRARY_PATH=/usr/local/lib/ worked!

Thank you.
Do you think I should just have that exported in my bashrc?

I have another question. Kind of outside the scope if you don't mind too much...
I have pin 11 on my AGX Xavier going to a button on a bread board. How does one complete the circuit of the button so that it works? Same with the LED coming from pin 7. Do I complete the circuits by attaching the other end of the LED and button to any ground pins? Sorry for the rookie question, but these answers are harder to dig up than they are for an Arduino.

pjueon commented 2 years ago

Ok, if that fix your problem, sudo vi /etc/ld.so.conf and add a line include /usr/local/lib. And then run sudo lpcofig. (Check https://stackoverflow.com/questions/4743233/is-usr-local-lib-searched-for-shared-libraries)

About circuit, I think you should complete the circuit if I understand your description correctly. Or you can just try both ways and see if it works :).

MotorCityCobra commented 2 years ago

I think you should complete the circuit if I understand your description correctly.

Right. Have you used a Jetson for buttons and LEDs? If I have a wire going from pin 11 to an LED, where does the other LED's wire get connected to complete the circuit? I thought it was the ground, but I didn't get anything from the scripts with a button and LED connected to the right GPIO pins and ground pins.

pjueon commented 2 years ago

Ok I've just added the comments about the example sample setup in samples/button_event.cpp file.

Basically something like this: example

If you push the button, pin 11 become LOW. If you release the button, pin 11 become HIGH.

So when you push the button pin 11 will be changed HIGH to LOW (FALLING EDGE).

The sample program waits until the FALLING EDGE event is detected in pin 11. If the event is detected, it turns the LED on for 1 second.

MotorCityCobra commented 2 years ago

Thank you. Very generous with all the detail.

Are these the same pin numbers? I'm not getting anything from the LED and no response from pushing the button When it's pin 7 and pin 11 in your code is it pin 7 and 11 in this diagram, or is there another layer of translation I'm missing?

3457356uj564e

pjueon commented 2 years ago

It's using the BOARD numbering mode so it should be the same pin numbering as the image.

Hmm...

  1. What pins are you using for 3.3V and GND?

  2. Without any program, can you check if your button and LED with something like this? Does the LED turn on when you push the button? example2

  3. Can you post the output of the code after editing the button_event.cpp like below?


#include <signal.h>

#include <chrono>
#include <iostream>
#include <thread>

#include <JetsonGPIO.h>

using namespace std;

static bool end_this_program = false;

inline void delay(int s) { this_thread::sleep_for(chrono::seconds(s)); }

void signalHandler(int s) { end_this_program = true; }

int main()
{
    // When CTRL+C pressed, signalHandler will be called
    signal(SIGINT, signalHandler);

    // Pin Definitions
    int led_pin = 7;  // BOARD pin 7
    int but_pin = 11; // BOARD pin 11

    // Pin Setup.
    GPIO::setmode(GPIO::BOARD);

    // set pin as an output pin with optional initial state of LOW
    GPIO::setup(led_pin, GPIO::OUT, GPIO::LOW);
    GPIO::setup(but_pin, GPIO::IN);

    cout << "Starting demo now! Press CTRL+C to exit" << endl;

    std::cout << "[DEBUG] model: " << GPIO::model << std::endl;
    std::cout << "[DEBUG] input on pin " << but_pin << ": " << GPIO::input(but_pin) << std::endl;

    while (!end_this_program) {
        cout << "Waiting for button event" << endl;
        GPIO::wait_for_edge(but_pin, GPIO::Edge::FALLING);

        // event received when button pressed
        cout << "Button Pressed!" << endl;
        GPIO::output(led_pin, GPIO::HIGH);
        delay(1);
        GPIO::output(led_pin, GPIO::LOW);
    }

    GPIO::cleanup();

    return 0;
}
MotorCityCobra commented 2 years ago

When using pin 1, which is a 3.3V pin and a ground pin (6) I get light out of an LED with two resistors(?).

Output of that script.

$ ./button_event [WARNING] This channel is already in use, continuing anyway. Use GPIO::setwarnings(false) to disable warnings. Starting demo now! Press CTRL+C to exit [DEBUG] model: JETSON_XAVIER [DEBUG] input on pin 11: 0 Waiting for button event

I even tried a gpio Python library and a script to try to get a single LED to turn on and that didn't work. Following this tutorial.

When I check the pins with an electrometer pins 7 and 11 have about 0.1V, and they don't seem to be changing when the 'OFF, ON, OFF, ON' signals are supposedly being sent to the pins.

Weird! I wonder what is wrong with my Jetson. The electrometer reads 3.3V and the 3.3V pins. I wonder if the gpio problem is something physically wrong with the pins or if it is maybe a problem with the Jetpack version!

MotorCityCobra commented 2 years ago

Alright, I think I need to buy PN2222 transistors to use the gpio pins on this fucking thing. Pardon my French.
This thing is 30 times more expensive than an Arduino or RBPi but have to buy little parts and screw around with the most complex and janky looking setup to get a signal out of it.

Video on the topic

Although in this tutorial he doesn't seem to be using that type of transistor.

UPDATE: I just bought a few transistors at the computer store. They didn't work. I can't use anything in Python or C++ to get the gpio pins to control an LED.

pjueon commented 2 years ago

About: When I check the pins with an electrometer pins 7 and 11 have about 0.1V + [DEBUG] input on pin 11: 0

Is this result from the first setup(the first image I posted)? or the second setup?

I'm assuming it's from the second setup. Can you retry it with the first setup?

If it's from the first setup, something is wrong with your circuit probably. In the first setup pin 11 should be HIGH when the button is not pushed even without the program because pin 11 is connected to 3.3V pin.

And getting warning is bit weird too. Maybe is it because you tested the same pin with python and didn't cleanup? Hmm...

By the way, I didn't know somebody wrote a tutorial using this library. I'm really glad!

pjueon commented 2 years ago

Ok, create a new .cpp file to check the input first.


#include <signal.h>

#include <chrono>
#include <iostream>
#include <thread>

#include <JetsonGPIO.h>

using namespace std;

static bool end_this_program = false;

inline void delay(int s) { this_thread::sleep_for(chrono::seconds(s)); }

void signalHandler(int s) { end_this_program = true; }

int main()
{
    // When CTRL+C pressed, signalHandler will be called
    signal(SIGINT, signalHandler);

    // Pin Definitions
    int led_pin = 7;  // BOARD pin 7
    int but_pin = 11; // BOARD pin 11

    // Pin Setup.
    GPIO::setmode(GPIO::BOARD);

    // set pin as an output pin with optional initial state of LOW
    GPIO::setup(led_pin, GPIO::OUT, GPIO::LOW);
    GPIO::setup(but_pin, GPIO::IN);

    cout << "input test! Press CTRL+C to exit" << endl;

    while (!end_this_program) {
        GPIO::output(led_pin, GPIO::HIGH);
        std::cout << "should be HIGH" << std::endl;
        std::cout << "input: " << GPIO::input(but_pin) << std::endl;
        delay(1);
        GPIO::output(led_pin, GPIO::LOW);
        std::cout << "should be LOW" << std::endl;
        std::cout << "input: " << GPIO::input(but_pin) << std::endl;
        delay(1);
    }

    GPIO::cleanup();

    return 0;
}
  1. Connect the pin 7 and 11 directly without any other circuit. And run the above program. (loopback test)
  2. Connect pin 11 to 3.3V directly without any other circuit and retry. The input should be 1 always.
  3. Connect pin 11 to GND directly without any other circuit and retry. The input should be 0 always.

If 1, 2, 3 works, everything is normal.
If only 2, 3 works, the input from pin 11 is working but output from pin 7 is not working. If none of them works, the input from pin 11 is not working. In that case, change the pin number in the program and try it with other pins(make sure that you're not connecting the GND to output (3.3V, 5V or the pin you set to output)

MotorCityCobra commented 2 years ago

I tried all three. I got the same output each time.

Pin 7 and pin 11 connected

should be HIGH
input: 0
should be LOW
input: 0
should be HIGH
input: 0
should be LOW
input: 0
should be HIGH
input: 0
should be LOW
input: 0

11 to 3.3V has the same output as above. Input: 0

11 to ground is also same. Input: 0

From your comment above

Is this (electrometer) result from the first setup(the first image I posted)? or the second setup?

It seems like the pins have 0.1V unless they are the 3.3V or 5V. The gpio pins are just dead metal that don't have any signal.
I'm thinking the problem is Jetpack or maybe the device was fried by the previous owner.

pjueon commented 2 years ago

Hmm.. so that means the input is not working...

When you are running the program, open an another terminal and run sudo /opt/nvidia/jetson-io/jetson-io.py

On the jetson-io, can you see pin 7 and 11 are using?

MotorCityCobra commented 2 years ago

run sudo /opt/nvidia/jetson-io/jetson-io.py

You want me to run this with Python?

On the jetson-io, can you see pin 7 and 11 are using?

Sorry, I don't know what you're asking exactly.

pjueon commented 2 years ago

sudo /opt/nvidia/jetson-io/jetson-io.py or sudo python3 /opt/nvidia/jetson-io/jetson-io.py

something like this: io

about jetson-io(https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_io.html)

If you set the pins input/output(by python or c++) probably you can see it from jetson-io.

pjueon commented 2 years ago

Hmm... but if the program is running without throwing any error, I think the software is running correctly. And you got the same result with the python library, it's probably not a software problem.

MotorCityCobra commented 2 years ago
$ sudo python3 /opt/nvidia/jetson-io/jetson-io.py
Traceback (most recent call last):
  File "/opt/nvidia/jetson-io/jetson-io.py", line 594, in <module>
    curses.wrapper(JetsonIO)
  File "/usr/lib/python3.6/curses/__init__.py", line 73, in wrapper
    stdscr = initscr()
  File "/usr/lib/python3.6/curses/__init__.py", line 30, in initscr
    fd=_sys.__stdout__.fileno())
_curses.error: setupterm: could not find terminal

Hmm... but if the program is running without throwing any error, I think the software is running correctly.

If it's not something burned out with the hardware it must be a problem with Jetpack or pin configuration option that is obviously over my head. I played that video earlier with a PN2222 transistor. I went to the computer store. They didn't have that transistor but I bought a few around the same size and they didn't work.

pjueon commented 2 years ago

Hmm.. Honestly I don't know how to investigate further, sorry.

If you cannot control your GPIO with the official python library too, it might be a good idea to ask to them some advice (https://github.com/NVIDIA/jetson-gpio).

MotorCityCobra commented 2 years ago

I got the screen with sudo /opt/nvidia/jetson-io/jetson-io.py working in the terminal. I overcame the error.

Mine looks like yours.
Can I do anything with this?

pjueon commented 2 years ago

When you are running the program, open an another terminal and run jetson-io.

If you set the pins input/output(by python or c++), probably you can see it from jetson-io(unused to input or output).

At the end of the program, JetsonGPIO will clean up all channels that were used. So if you need to run jetson-io while the program is running.

It's just checking if the pin setting is changed or not.

MotorCityCobra commented 2 years ago

I've managed to more or less solve the problem and get blinking lights controlled by Python and C++ scripts, like the ones in your repo.

On this site Some of the pins are labelled '1.8/3.3V'. These pins do NOT toggle lights or seem to respond in any way. These were the pins 7, 11, and 13, that I spent so much time on.
Pins such as 37 are labelled 3.3V and they DO toggle lights. When I check them with an electrometer I get the same readouts. 3.3V and 0V on the pins with just 3.3V and no changes when I try to use software to toggle the pins labelled '1.8/3.3V'. I don't know what to do with these pins!

I don't know if this is just something with the Xavier.

pjueon commented 2 years ago

On this site Some of the pins are labelled '1.8/3.3V'. These pins do NOT toggle lights or seem to respond in any way. These were the pins 7, 11, and 13, that I spent so much time on. Pins such as 37 are labelled 3.3V and they DO toggle lights. When I check them with an electrometer I get the same readouts. 3.3V and 0V on the pins with just 3.3V and no changes when I try to use software to toggle the pins labelled '1.8/3.3V'. I don't know what to do with these pins!

Thank you for the information.

On the site you linked: The initial pinmux should set all of the these pins, except for the power, UART RX TX and two I2C busses, to GPIO at boot. The UART and I2C busses should not be used for GPIO.

According to the link, looks like pin 3, 5, 8, 10, 27, 28 cannot be used as GPIO in Xavier by the default. Hmm.. I'm not really sure why you can't use pin 7, 11 and 13 but it's probably because of your board configurations. I think probably there is a way to change the pin configurations for your board, but that might not be the topic that we should discuss here(maybe you should ask to the official python library's repository)

Thank you for the information again. And I'm glad that the library works on your device!

MotorCityCobra commented 2 years ago

I didn't look at all your scripts. Do any of them use stepper motors?
I'd eventually like to connect stepper motors, encoders, gyros, and accelerometers to the Xavier. I see there are only three PWM pins on it. Do you have any suggestions or direction I can go in to get started with this? It seems like another thing that there is little documentation of that I will have to spend all day every day for a week trying to figure out. For two weeks before this I spent all day every day figuring out how to try to install LibTorch onto the device.
It's like the Xavier was beamed to me from another planet. wah wah wah. Thanks.

pjueon commented 2 years ago

There is no sample script using step motors. There is a sample script about pwm: samples/simple_pwm.cpp. You can see how to control pwm by the library.

Do you have any suggestions or direction I can go in to get started with this?

I'm not very familiar with hardware or circuits, so I cannot give any advice about that kind of stuff.