EV3 BCC / C software problem(s)
Re: EV3 BCC / C software problem(s)
Quite some time ago I told doc to add "-lpthread" to the LDFLAGS line in the makefile template. If he doesn't have a line that starts with LDFLAGS then he has an old template and needs to click Default on that page - and be running the latest BricxCC test release.
If he were to look in the template he would see where LDFLAGS winds up being used further down in the template. It would show him that anything he puts into the LDFLAGS value would get passed into the linker. Alternatively, he could add -lpthread to the end of the line with %LINKOBJS% on it, separated by a space, just below the comment which says "how to link executable".
The most important thing for Doc to do is to google "makefile tutorial" or something similar and read a bit. I strongly suspect he would find tutorials on the web written in his native language even. But certainly he would find a lot that are very easy to read and follow. He could even try reading the PDF documentation that comes with the CodeSourcery Lite compiler. It is also easy to read and follow.
The "-l" switch for GCC says "link with the following library" and it is followed by the library name without "lib" and ".so", e.g., libpthread.so would be linked with by adding -lpthread to the compiler command line. If you need to link with a lot of libraries then you add each one, e.g., -lev3 -lpthread -lusb, would link with libev3.so, libpthread.so, and libusb.so.
John Hansen
If he were to look in the template he would see where LDFLAGS winds up being used further down in the template. It would show him that anything he puts into the LDFLAGS value would get passed into the linker. Alternatively, he could add -lpthread to the end of the line with %LINKOBJS% on it, separated by a space, just below the comment which says "how to link executable".
The most important thing for Doc to do is to google "makefile tutorial" or something similar and read a bit. I strongly suspect he would find tutorials on the web written in his native language even. But certainly he would find a lot that are very easy to read and follow. He could even try reading the PDF documentation that comes with the CodeSourcery Lite compiler. It is also easy to read and follow.
The "-l" switch for GCC says "link with the following library" and it is followed by the library name without "lib" and ".so", e.g., libpthread.so would be linked with by adding -lpthread to the compiler command line. If you need to link with a lot of libraries then you add each one, e.g., -lev3 -lpthread -lusb, would link with libev3.so, libpthread.so, and libusb.so.
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Re: EV3 BCC / C software problem(s)
I don't know what a "makefile template" is and I have no imagination of LDFLAGS or what this is all about the "link with..."
do you mean that edit field with
should it look like this:
?
this looks not very convincing...
The only fields with flags in it I could find is "GCC flags" "FPC flags" in edit/preferences/compiler, no idea if you mean this instead, and I actually expected something additionally like edit/preferences/makefile or edit/preferences/linker or edit/preferences/linkto in the IDE.
But I actually don't like to make a makefile tutorial or a gcc tutorial just in order to enable multithreading, I expect the IDE to do the important stuff automatically.
So I would appreciate one or the other screenshot how to do it.
do you mean that edit field with
Code: Select all
PROGRAM=%PROGRAM%
DOBJECTS=%DOBJECTS%
TOOLPREFIX=%TOOLPREFIX%
all:: realclean $(DOBJECTS) $(PROGRAM)
Code: Select all
PROGRAM=%PROGRAM%
DOBJECTS=%DOBJECTS%
TOOLPREFIX=%TOOLPREFIX%
all:: realclean $(DOBJECTS) $(PROGRAM)
-lpthread
this looks not very convincing...
The only fields with flags in it I could find is "GCC flags" "FPC flags" in edit/preferences/compiler, no idea if you mean this instead, and I actually expected something additionally like edit/preferences/makefile or edit/preferences/linker or edit/preferences/linkto in the IDE.
But I actually don't like to make a makefile tutorial or a gcc tutorial just in order to enable multithreading, I expect the IDE to do the important stuff automatically.
So I would appreciate one or the other screenshot how to do it.
Re: EV3 BCC / C software problem(s)
edit,
new try:
I tried that with
LIBS=-lpthread
(thanks to Xander!)
in the big edit field with this code:
I get the error:
but that's too complicated to see through for me.
new try:
I tried that with
LIBS=-lpthread
(thanks to Xander!)
in the big edit field with this code:
Code: Select all
// Multitasking-Demo:
// 3 Motoren an die Motorausgänge A,B,C anschließen !
// die Motoren werden automatisch angesteuert,
// die Encoderwerte werden simultan angezeigt!
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include "ev3_constants.h"
#include "ev3_command.h"
#include "ev3_button.h"
#include "ev3_timer.h"
#include "ev3_lcd.h"
#include "ev3_sound.h"
#include "ev3_output.h"
#define clreol DRAW_OPT_CLEAR_EOL
void *DisplayValues(void *threadid) {
while(true) {
TextOut(0,56, "Enc.A: "); NumOut(42,56, MotorRotationCount(OUT_A));
TextOut(0,48, "Enc.B: "); NumOut(42,48, MotorRotationCount(OUT_B));
TextOut(0,40, "Enc.C: "); NumOut(42,40, MotorRotationCount(OUT_C));
Wait(40);
}
pthread_exit(0);
}
void *MotorControl(void *threadid) {
int speed;
while(true) {
speed=Random(201) - 100; // ergibt eine Zufallszahl für die Motorleistung zwischen -100 und +100
OnFwd(OUT_A);
speed=Random(201) - 100;
OnFwd(OUT_B);
speed=Random(201) - 100;
OnFwd(OUT_C);
Wait( 200+ (Random(2800)) ); // ergibt eine Zufallszahl für die Aktionsdauer von 200 - 3000 ms
}
pthread_exit(0);
}
main() {
pthread_t f2_thread, f1_thread;
pthread_create(&f1_thread,NULL,MotorControl,NULL);
pthread_create(&f2_thread,NULL,DisplayValues,NULL);
pthread_join(f1_thread,NULL);
pthread_join(f2_thread,NULL);
}
I get the error:
maybe it's a project file issue?Errors found during compilation
...
[F12]
c:\Temp\ccO5orTW.o: In function `DisplayValues':
mt-demo.c:(.text+0x20): undefined reference to `TextOutEx'
mt-demo.c:(.text+0x28): undefined reference to `MotorRotationCount'
mt-demo.c:(.text+0x40): undefined reference to `NumOutEx'
mt-demo.c:(.text+0x54): undefined reference to `TextOutEx'
mt-demo.c:(.text+0x5c): undefined reference to `MotorRotationCount'
mt-demo.c:(.text+0x74): undefined reference to `NumOutEx'
mt-demo.c:(.text+0x88): undefined reference to `TextOutEx'
mt-demo.c:(.text+0x90): undefined reference to `MotorRotationCount'
mt-demo.c:(.text+0xa8): undefined reference to `NumOutEx'
mt-demo.c:(.text+0xb0): undefined reference to `Wait'
c:\Temp\ccO5orTW.o: In function `MotorControl':
mt-demo.c:(.text+0xd8): undefined reference to `Random'
mt-demo.c:(.text+0xf4): undefined reference to `OnFwdEx'
mt-demo.c:(.text+0xfc): undefined reference to `Random'
mt-demo.c:(.text+0x118): undefined reference to `OnFwdEx'
mt-demo.c:(.text+0x120): undefined reference to `Random'
mt-demo.c:(.text+0x13c): undefined reference to `OnFwdEx'
mt-demo.c:(.text+0x144): undefined reference to `Random'
mt-demo.c:(.text+0x154): undefined reference to `Wait'
c:\Temp\ccO5orTW.o: In function `main':
mt-demo.c:(.text+0x17c): undefined reference to `pthread_create'
mt-demo.c:(.text+0x194): undefined reference to `pthread_create'
mt-demo.c:(.text+0x1a4): undefined reference to `pthread_join'
mt-demo.c:(.text+0x1b4): undefined reference to `pthread_join'
collect2: ld returned 1 exit status
make: *** [mt-demo] Error 1
but that's too complicated to see through for me.
Re: EV3 BCC / C software problem(s)
It is certain that if the edit window on the Compilers/EV3 tab that says "Makefile template" next to it does not contain the word "LDFLAGS" then you have an old template and you need to click the Default button on that tab, if you are running the very latest BricxCC test release. This will reset all compiler settings, including your NXC compiler settings, to their default values. If this concerns you then I recommend taking screenshots of the other tabs so you can change the values as needed.
People who don't know how BricxCC creates and uses a Makefile have given you bad suggestions. If you just listened to what I said for a change then everything would work just fine.
Step 1: Get a makefile template that mentions "LDFLAGS" by clicking the Default button.
Step 2: Add -lpthread to the end of the line that starts with LDFLAGS= with a space separating the - from whatever is in front of it.
Step 3: Read the readme_1st.txt and do what it says in step 30, i.e., create a Project file and add the necessary ev3_*.c files to it.
Step 4: As an alternative to step 3 add -lev3 to the end of the line that starts with LDFLAGS= and make sure that libev3.so is in the same folder as your source file.
If you say "too many words" or "that's too hard for people to understand" then you will not see me ever trying to help you again.
John Hansen
People who don't know how BricxCC creates and uses a Makefile have given you bad suggestions. If you just listened to what I said for a change then everything would work just fine.
Step 1: Get a makefile template that mentions "LDFLAGS" by clicking the Default button.
Step 2: Add -lpthread to the end of the line that starts with LDFLAGS= with a space separating the - from whatever is in front of it.
Step 3: Read the readme_1st.txt and do what it says in step 30, i.e., create a Project file and add the necessary ev3_*.c files to it.
Step 4: As an alternative to step 3 add -lev3 to the end of the line that starts with LDFLAGS= and make sure that libev3.so is in the same folder as your source file.
If you say "too many words" or "that's too hard for people to understand" then you will not see me ever trying to help you again.
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Re: EV3 BCC / C software problem(s)
thank you, by this screenshot I could understand it.
now this is my edit text window:
the project manager contains everything of the pattern "ev3_*.c"
SetMotor is still of incorrect use (outcommented)
this is my current code:
no error by F5
but absolutely nothing happens when I press ctrl+F5 except there is this file shown on the ev3 screen:
mt-demo
if I try to start the file via BCC Explorer tool nothing happens neither (I observed that the EV3 hung up/ was blocked).
if I press the Center Button (because nothing happened instead) there is an ugly sound like "taaa-da" and the display shows:
The Lego Demo file runs fine anyway, so the EV3 brick is ok.
now this is my edit text window:
Code: Select all
PROGRAM=%PROGRAM%
DOBJECTS=%DOBJECTS%
TOOLPREFIX=%TOOLPREFIX%
all:: realclean $(DOBJECTS) $(PROGRAM)
download:: all
#pscp -scp -pw "%PW%" %PROGRAM% root@%IPADDR%:%FOLDER%
clean::
rm -f *.o *.ppu *.rst
realclean:: clean
rm -f $(PROGRAM)
FLAGS=%FLAGS%
LDFLAGS=-Wl,-R/media/card/lib -lpthread
CC=$(TOOLPREFIX)%CCNAME%
# how to link executable
%PROGRAM%: %MAINSRC%
$(CC) $(FLAGS) $(LDFLAGS) $< -o$@ %LINKOBJS%
# how to compile source
%.o: %%EXT%
$(CC) $(FLAGS) %LINKONLY% $< -o$@
SetMotor is still of incorrect use (outcommented)
this is my current code:
Code: Select all
// mt-demo.c
// Multitasking-Demo:
// 3 Motoren an die Motorausgänge A,B,C anschließen !
// die Motoren werden automatisch angesteuert,
// die Encoderwerte werden simultan angezeigt!
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include "ev3_constants.h"
#include "ev3_command.h"
#include "ev3_button.h"
#include "ev3_timer.h"
#include "ev3_lcd.h"
#include "ev3_sound.h"
#include "ev3_output.h"
#define clreol DRAW_OPT_CLEAR_EOL
void *DisplayValues(void *threadid) {
while(true) {
TextOut(0,56, "Enc.A: "); NumOut(42,56, MotorRotationCount(OUT_A));
TextOut(0,48, "Enc.B: "); NumOut(42,48, MotorRotationCount(OUT_B));
TextOut(0,40, "Enc.C: "); NumOut(42,40, MotorRotationCount(OUT_C));
Wait(40);
}
pthread_exit(0);
}
inline unsigned long Random(unsigned long x) {
return (rand() % x);
}
void *MotorControl(void *threadid) {
int speed;
while(true) {
speed=Random(201) - 100; // ergibt eine Zufallszahl für die Motorleistung zwischen -100 und +100
//SetMotor(OUT_A,speed);
OnFwd(OUT_A);
speed=Random(201) - 100;
//SetMotor(OUT_B,speed);
OnFwd(OUT_B);
speed=Random(201) - 100;
//SetMotor(OUT_C,speed);
OnFwd(OUT_C);
Wait( 200+ (Random(2800)) ); // ergibt eine Zufallszahl für die Aktionsdauer von 200 - 3000 ms
}
pthread_exit(0);
}
main() {
pthread_t f2_thread, f1_thread;
pthread_create(&f1_thread,NULL,MotorControl,NULL);
pthread_create(&f2_thread,NULL,DisplayValues,NULL);
pthread_join(f1_thread,NULL);
pthread_join(f2_thread,NULL);
}
but absolutely nothing happens when I press ctrl+F5 except there is this file shown on the ev3 screen:
mt-demo
if I try to start the file via BCC Explorer tool nothing happens neither (I observed that the EV3 hung up/ was blocked).
if I press the Center Button (because nothing happened instead) there is an ugly sound like "taaa-da" and the display shows:
Admittedly, the last thing was expected though./ ! \ error!
[OK]
The Lego Demo file runs fine anyway, so the EV3 brick is ok.
Re: EV3 BCC / C software problem(s)
I was about to try your program myself but then I noticed you seem to have ignored my test programs.
Notice the first function call in the LCD test program. Notice the fourth function call in the Output test program. Also, can you tell me what on earth is this SetMotor function you are trying to call? If you look in the Output test program you will see how to set the power level of the outputs. Hint: it is the same as in the NQC API.
http://bricxcc.sourceforge.net/nqc/doc/NQC_Guide.pdf
All of the API functions are written to do nothing if the associated module has not yet been initialized. This could possibly be changed in the future.
John Hansen
Notice the first function call in the LCD test program. Notice the fourth function call in the Output test program. Also, can you tell me what on earth is this SetMotor function you are trying to call? If you look in the Output test program you will see how to set the power level of the outputs. Hint: it is the same as in the NQC API.
http://bricxcc.sourceforge.net/nqc/doc/NQC_Guide.pdf
All of the API functions are written to do nothing if the associated module has not yet been initialized. This could possibly be changed in the future.
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Re: EV3 BCC / C software problem(s)
of course I did, the LCD and sound test programs run fine (I already reported that some time before)
By outtest.c the motor is running but just 1 sec instead of 5 sec, even if I enlarge the seconds to wait to 20 sec:
(I'm curious if I'm the only one who tried and then came upon this issue)
In my mt-demo.c I exchanged SetMotor by SetPower.
By outtest.c the motor is running but just 1 sec instead of 5 sec, even if I enlarge the seconds to wait to 20 sec:
Code: Select all
#include <stdio.h>
#include <unistd.h>
#include "ev3_output.h"
#include "ev3_timer.h"
#include "ev3_command.h"
int main()
{
int i;
printf("hello world\n");
printf("start of out_test\n");
Wait(SEC_1);
// initialize
if (!OutputInit())
printf("output init returned false\n");
ResetAllTachoCounts(OUT_ABCD);
OutputSetTypes(DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO);
RotateMotor(OUT_AB, 75, 360); //works
//RotateMotor(OUT_A,75, 360); //crashes
printf("Wait(SEC_20)\n");
Wait(SEC_20); // alternatively also tried: Wait (20000)
OutputClose();
OutputExit();
printf("end of out_test\n");
return 0;
}
In my mt-demo.c I exchanged SetMotor by SetPower.
Re: EV3 BCC / C software problem(s)
now I added
at start of main().
EDIT:
the following was still missing:
the code now looks like this:
result:
motors start driving, but constantly / continuously, no change in direction, program hangs up, blocks, batteries need to be removed.
If possible, please modify the whole code so that it is able to work as expected, I then will try to transform the changes to other programs in future.
Thanks in advance!
Code: Select all
int i;
printf("hello world\n");
printf("start of mt-demo\n");
Wait(SEC_1);
// initialize
if (!OutputInit())
printf("output init returned false\n");
ResetAllTachoCounts(OUT_ABCD);
OutputSetTypes(DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO);
EDIT:
the following was still missing:
Code: Select all
OutputClose();
OutputExit();
Code: Select all
// mt-demo.c
// 0.3
// Multitasking-Demo:
// 3 Motoren an die Motorausgänge A,B,C anschließen !
// die Motoren werden automatisch angesteuert,
// die Encoderwerte werden simultan angezeigt!
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include "ev3_constants.h"
#include "ev3_command.h"
#include "ev3_button.h"
#include "ev3_timer.h"
#include "ev3_lcd.h"
#include "ev3_sound.h"
#include "ev3_output.h"
#define clreol DRAW_OPT_CLEAR_EOL
void *DisplayValues(void *threadid) {
while(true) {
TextOut(0,56, "Enc.A: "); NumOut(42,56, MotorRotationCount(OUT_A));
TextOut(0,48, "Enc.B: "); NumOut(42,48, MotorRotationCount(OUT_B));
TextOut(0,40, "Enc.C: "); NumOut(42,40, MotorRotationCount(OUT_C));
Wait(40);
}
pthread_exit(0);
}
inline unsigned long Random(unsigned long x) {
return (rand() % x);
}
void *MotorControl(void *threadid) {
int speed;
while(true) {
speed=Random(201) - 100; // ergibt eine Zufallszahl für die Motorleistung zwischen -100 und +100
SetPower(OUT_A,speed);
OnFwd(OUT_A);
speed=Random(201) - 100;
SetPower(OUT_B,speed);
OnFwd(OUT_B);
speed=Random(201) - 100;
SetPower(OUT_C,speed);
OnFwd(OUT_C);
Wait( 200+ (Random(2800)) ); // ergibt eine Zufallszahl für die Aktionsdauer von 200 - 3000 ms
}
pthread_exit(0);
}
main() {
int i;
printf("hello world\n");
printf("start of mt-demo\n");
Wait(SEC_1);
// initialize
if (!OutputInit())
printf("output init returned false\n");
ResetAllTachoCounts(OUT_ABCD);
OutputSetTypes(DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO, DEVICE_TYPE_TACHO);
pthread_t f2_thread, f1_thread;
pthread_create(&f1_thread,NULL,MotorControl,NULL);
pthread_create(&f2_thread,NULL,DisplayValues,NULL);
pthread_join(f1_thread,NULL);
pthread_join(f2_thread,NULL);
OutputClose();
OutputExit();
}
motors start driving, but constantly / continuously, no change in direction, program hangs up, blocks, batteries need to be removed.
If possible, please modify the whole code so that it is able to work as expected, I then will try to transform the changes to other programs in future.
Thanks in advance!
Re: EV3 BCC / C software problem(s)
Doc,
You know your program can't ever end since the two threads go on forever, right? That means the VM will look like it is hung since it is waiting for your program to quit running.
Why did you add anything other than the OutputInit call and why did you leave out the required LCDInit call? One of your threads is trying to draw on the LCD which it cannot do if you have not initialized the LCD module.
It would help if you try the out_test_c.c that comes with the API zip and not a version I do not recognize even slightly. In the code you posted it never ever tries to rotate any motors for 5 seconds. And RotateMotor waits until the rotation has completed so it has finished and stopped the motors before execution goes on to the Wait statement. Why are you calling OutputSetTypes? You can see that I do not call that function at all in my sample test programs.
If you think that calling OnFwd with a negative power should reverse the motor I think you might be mistaken (though I could be wrong). What does the NQC API say OnFwd does? "Set outputs to forward direction and turn them on". If you don't want to confuse the the EV3 by toggling the direction via OnFwd and OnRev and you want the power level to be the only factor that influences direction then I would recommend using On instead of OnFwd or OnRev. The latter two functions adjust the polarity on the outputs which, in my testing, did not seem to work reliably in the firmware, but it is possible I am not using it correctly. My point being that you should stick to either positive power levels and direction/polarity toggling OR you should use positive and negative power levels and leave the direction toggling alone but don't mix the two things together.
John Hansen
You know your program can't ever end since the two threads go on forever, right? That means the VM will look like it is hung since it is waiting for your program to quit running.
Why did you add anything other than the OutputInit call and why did you leave out the required LCDInit call? One of your threads is trying to draw on the LCD which it cannot do if you have not initialized the LCD module.
It would help if you try the out_test_c.c that comes with the API zip and not a version I do not recognize even slightly. In the code you posted it never ever tries to rotate any motors for 5 seconds. And RotateMotor waits until the rotation has completed so it has finished and stopped the motors before execution goes on to the Wait statement. Why are you calling OutputSetTypes? You can see that I do not call that function at all in my sample test programs.
If you think that calling OnFwd with a negative power should reverse the motor I think you might be mistaken (though I could be wrong). What does the NQC API say OnFwd does? "Set outputs to forward direction and turn them on". If you don't want to confuse the the EV3 by toggling the direction via OnFwd and OnRev and you want the power level to be the only factor that influences direction then I would recommend using On instead of OnFwd or OnRev. The latter two functions adjust the polarity on the outputs which, in my testing, did not seem to work reliably in the firmware, but it is possible I am not using it correctly. My point being that you should stick to either positive power levels and direction/polarity toggling OR you should use positive and negative power levels and leave the direction toggling alone but don't mix the two things together.
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
http://bricxcc.sourceforge.net/
Re: EV3 BCC / C software problem(s)
I'm actually not quite sure what you mean which function is probably safe or not safe for BCC/C.
So 1 question before I'll change my code:
In NXC OnFwd(outputs, pwr) is fine for positive and/or negative pwr values, I use it successfully for my multithreaded PID position control.
So provided that I need a BCC/C function which switchs a motor forward or reverse depending on the signum of the pwr value -
do you think that On() is safe for positive and negative values in BCC/C ?
or do you think sth like the following will be more safe ?
it's admittedly a little complex but should work (CMIIW).
So 1 question before I'll change my code:
In NXC OnFwd(outputs, pwr) is fine for positive and/or negative pwr values, I use it successfully for my multithreaded PID position control.
So provided that I need a BCC/C function which switchs a motor forward or reverse depending on the signum of the pwr value -
do you think that On() is safe for positive and negative values in BCC/C ?
or do you think sth like the following will be more safe ?
Code: Select all
inline void Motor(int outputs, int pwr) {
int buf=pwr;
pwr=abs(pwr);
SetPower(outputs, pwr);
if(buf>=0) {OnFwd(outputs);}
else {OnRev(outputs);}
}
Who is online
Users browsing this forum: No registered users and 1 guest