Reading analog inputs fast in beaglebone black - beagleboneblack

I need to read all 7 analog pins in the BBB every 5 milliseconds. I'm doing so with the following C code:
void main(){
char value_str[7];
long int value_int = 0;
FILE* f0 = fopen("/sys/bus/iio/devices/iio:device0/in_voltage0_raw", "r");
while(1){
fread(&value_str, 6, 6, f0);
value_int = strtol(value_str,NULL,0);
printf("0 %li\n", value_int);
fflush(stdout);
usleep(5000);
rewind(f0);
}
Hoever, the cpu usage goes up really high (20%). Is there any way to read the analog inputs differently so that it doesn't use as much CPU? Someone suggested "DMA" but I'm completely lost on that regard...
Any help will be appreciated.

This thread in the BBB forum was very useful and I ended up using libpruio. It uses the PRU to read the Beagle's built in io pins and analog to digital converters. The code I ended up using:
#include <stdio.h>
#include <unistd.h>
#include "pruio_c_wrapper.h"
#include "pruio_pins.h"
int main(int argc, const char *argv[]) {
PruIo *io = pruio_new(0, 0x98, 0, 1);
if (io->Errr) {
printf("Initialisation failed (%s)\n", io->Errr);
return 1;
}
if(pruio_config(io, 0, 0x1FE, 0, 4, 0)){
printf("Config failed (%s)\n", io->Errr);
return 1;
}
while(1){
printf"\r%12o %12o %12o %12o %4X %4X %4X %4X %4X %4X %4X %4X\n"
, io->Gpio[0].Stat, io->Gpio[1].Stat, io->Gpio[2].Stat, io->Gpio[3].Stat
, io->Value[1], io->Value[2], io->Value[3], io->Value[4], io->Value[5]
, io->Value[6], io->Value[7], io->Value[8]);
usleep(1000);
}
pruio_destroy(io);
return 0;
}

I suggest you use the PRU. It's very fast!
This should get you started->
http://www.element14.com/community/community/knode/single-board_computers/next-gen_beaglebone/blog/2013/08/04/bbb--high-speed-data-acquisition-and-web-based-ui

Related

Nested table built with Lua C API crashes

I'm trying to make a deeply nested table in Lua. When I nest past 16 levels my program crashes.
In the example program below, when I change DEPTH to 16 instead of 17 the program does not crash. I can't find any resources that say there is a maximum table depth, and one so low seems odd. The crash is within the call to lua_close().
Am I misunderstanding how to build a table in Lua using the C API, or is there in fact a maximum depth?
#include <assert.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#define DEPTH 17
int main(int argc, char* argv[])
{
lua_State *L = NULL;
size_t i = 0;
L = luaL_newstate();
assert(NULL!=L);
luaL_openlibs(L);
// create the root table
lua_newtable(L);
// push DEPTH levels deep onto the table
for (i=0; i<DEPTH; i++)
{
lua_pushstring(L, "subtable");
lua_newtable(L);
}
// nest the DEPTH levels
for (i=0; i<DEPTH; i++)
{
lua_settable(L, -3);
}
lua_close(L);
return 0;
}
You need to increase the stack with lua_checkstack or luaL_checkstack to allow 2*DEPTH slots.

Compiler commands for accull while using opencv

I'm trying to accelerate an opencv program I wrote using OpenACC, I'm using the accull compiler to do this. However, I'm having a very hard time finding any documentation or examples that would help me on this issue.
http://scelementary.com/2015/04/30/openacc-on-jetson-tk1.html
I don't have any experience with ACCULL, but I can provide you with an example that uses OpenCV and OpenACC and maybe that'll help you get moving. This has been tested on X86 with PGI on Ubunut 14.04. This will read an image, invert the pixels, and write an image back out.
invert.cpp:
void invert(unsigned char *imgData, int w, int h, int ch, int step)
{
int i,j,c;
#pragma acc parallel loop collapse(3) copy(imgData[:h*w*ch])
for ( i = 0; i < h; i++)
for ( j = 0; j < w; j++ )
for ( c = 0; c < ch; c++ )
imgData[i*step + j*ch + c] = 255 - imgData[i*step + j*ch + c];
}
main.cpp:
#include <stdio.h>
#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include <opencv/highgui.h>
void invert(unsigned char*,int,int,int,int);
int main(int argc, char* argv[])
{
if (argc < 3)
{
fprintf(stderr,"Usage: %s inFilename outFilename\n",argv[0]);
return -1;
}
IplImage* img = cvLoadImage(argv[1]);
printf("%s: %d x %d, %d %d\n", argv[1],img->width, img->height, img->widthStep, img->nChannels);
invert((unsigned char*)img->imageData,img->width,img->height, img->nChannels, img->widthStep);
if(!cvSaveImage(argv[2],img))
fprintf(stderr,"Failed to write to %s.\n",argv[2]);
cvReleaseImage(&img);
return 0;
}
Makefile:
a.out: main.cpp invert.cpp
pgc++ -fast -ta=tesla -c invert.cpp
pgc++ -fast -ta=tesla -c main.cpp
pgc++ -ta=tesla invert.o main.o -lopencv_legacy -lopencv_highgui -lopencv_core

Using MPI_Send inside a pthread in C

i am trying to create a ring of mpi processes where each MPI process will launch a pthread and the threads will perform the ring, i used pthread so i can use the MPI processes to do another task. It seems that i can't use MPI_send or MPI_Recv inside a pthread, i have no compilation error but i do have a run time error.
i compile using this command
mpicc -lpthread threaded_ring.c
this is the runtime error
a.out:28372 terminated with signal 11 at PC=2aaaaaae312d SP=2aaab0771860. Backtrace:
/usr/lib64/libpsm_infinipath.so.1(psmi_mpool_get+0xd)[0x2aaaaaae312d]
a.out:28366 terminated with signal 11 at PC=333c00c110 SP=2aaab02d9698. Backtrace:
/lib64/libpthread.so.0(pthread_spin_lock+0x0)[0x333c00c110]
/usr/lib64/libpsm_infinipath.so.1(psmi_amsh_short_request+0x180)[0x2aaaaaad31b0]
/usr/lib64/libpsm_infinipath.so.1(+0xd9f6)[0x2aaaaaad49f6]
/usr/lib64/libpsm_infinipath.so.1(psm_mq_send+0x41)[0x2aaaaaaf5d51]
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(psm_send_pkt+0xb1)[0x2aaaaae0af21]
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(psm_istartmsgv+0x130)[0x2aaaaae0a010]
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(MPIDI_CH3_iStartMsgv+0x6)[0x2aaaaaddf1e6]
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(MPIDI_CH3_EagerContigSend+0x89)[0x2aaaaada6e39]
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(MPID_Send+0x116)[0x2aaaaade3136]
/usr/local/mpi/mvapich2/intel12/1.8.1/lib/libmpich.so.3(MPI_Send+0xf8)[0x2aaaaae2a408]
./a.out[0x4022ba]
/lib64/libpthread.so.0[0x333c0077f1]
/lib64/libc.so.6(clone+0x6d)[0x333bce570d]
a.out:28373 terminated with signal 11 at PC=333bf9d428 SP=2aaab0771838. Backtrace:
a.out:28370 terminated with signal 11 at PC=2aaaaaae312d SP=2aaab0771860. Backtrace:
here is my code
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
void *ring_func(void *p)
{
int token=1;
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
if (world_rank==0){
MPI_Send(&token, 1, MPI_INT, (world_rank + 1) % world_size, 0,
MPI_COMM_WORLD);
}
if (world_rank != 0) {
MPI_Recv(&token, 1, MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process %d received token %d from process %d\n", world_rank, token,
world_rank - 1);
}
pthread_exit(NULL);
}
int main(int argc, char** argv) {
// Initialize the MPI threaded environment
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE , &provided);
if (provided < MPI_THREAD_MULTIPLE)
{
printf("Error: the MPI library doesn't provide the required thread level\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
pthread_t ring ;
pthread_create (&ring, NULL, ring_func, NULL) ;
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}
Thanks to Hristo lliev i was able to solve the problem, the problem was that the main thread was finsishing before my pthread but when i added pthread_join the main thread waited for the pthread to join before calling MPI_Finalize(). Here is the new code
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
void *ring_func(void *p)
{
int token;
// Receive from the lower process and send to the higher process. Take care
// of the special case when you are the first process to prevent deadlock.
int world_rank;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
int world_size;
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
if (world_rank != 0) {
MPI_Recv(&token, 1, MPI_INT, world_rank - 1, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process %d received token %d from process %d\n", world_rank, token,
world_rank - 1);
} else {
// Set the token's value if you are process
token = -1;
}
MPI_Send(&token, 1, MPI_INT, (world_rank + 1) % world_size, 0,
MPI_COMM_WORLD);
if (world_rank == 0) {
// sleep(20);
MPI_Recv(&token, 1, MPI_INT, world_size - 1, 0, MPI_COMM_WORLD,
MPI_STATUS_IGNORE);
printf("Process %d received token %d from process %d\n", world_rank, token,
world_size - 1);
}
pthread_exit(NULL);
}
int main(int argc, char** argv) {
// Initialize the MPI threaded environment
int provided;
MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE , &provided);
if (provided != MPI_THREAD_MULTIPLE)
{
printf("Error: the MPI library doesn't provide the required thread level\n");
MPI_Abort(MPI_COMM_WORLD, 0);
}
pthread_t ring ;
pthread_create (&ring, NULL, ring_func, NULL) ;
pthread_join(ring,NULL);
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
}

lua5.2's error: multiple Lua VMs detected

I use 5.2 for learning recently, what I want to try like this:
Step 1, build a c module for lua:
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include <stdlib.h>
static int add(lua_State *L) {
int x = luaL_checkint(L, -2);
int y = luaL_checkint(L, -1);
lua_pushinteger(L, x + y);
return 1;
}
static const struct luaL_Reg reg_lib[] = {
{"add", add}
};
int luaopen_tool(lua_State *L) {
luaL_newlib(L, reg_lib);
lua_setglobal(L, "tool");
return 0;
}
I compile and link it with liblua.a, and I'm sure it works well in lua script like "require("tool") tool.add(1, 2)"
Step 2, I write another C program that wants to require my c module in step 1 like this:
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include <stdlib.h>
int main(int argc, char* const argv[]) {
lua_State *L = luaL_newstate();
luaL_requiref(L, "base", luaopen_base, 1);
luaL_requiref(L, "package", luaopen_package, 1);
lua_getglobal(L, "require");
if (!lua_isfunction(L, -1)) {
printf("require not found\n");
return 2;
}
lua_pushstring(L, "tool");
if (lua_pcall(L, 1, 1, 0) != LUA_OK) {
printf("require_fail=%s\n", lua_tostring(L, -1));
return 3;
}
lua_getfield(L, -1, "add");
lua_pushinteger(L, 2);
lua_pushinteger(L, 3);
lua_pcall(L, 2, 1, 0);
int n = luaL_checkint(L, -1);
printf("n=%d\n", n);
return 0;
}
I also compile & link with liblua.a, but error occurs when I run it:
"require_fail=multiple Lua VMs detected"
Someone's blog said that in lua5.2, you should link c module and c host program both dynamicly, but not staticly.
is there someone that has the same problem, or is there somehing wrong in my code, thanks.
NOTICE:
the problem has been solved by compile main program with -Wl,-E, thanks a lot for all your help ^^.
Don't link your C module with liblua.a when you create a .so from it. For examples, see my page of Lua libraries: http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/ . You can link liblua.a statically into your main program but you have to export its symbols by adding -Wl,-E at link time. That's how the Lua interpreter is built in Linux.

Can OpenCV be developed using C++ and C together

Can OpenCV be developed using C++ and C together? Following is the program where i meet this problem.It is coded with C and works well.But if I use
cv::Mat saveImage=cv::imread("D:\\opencvStudy\\opencv_test\\TaskDemo\\TaskDemo\\save.jpg");
cv::imshow("save",saveImage);
to replace
IplImage* saveImge =cvLoadImage("D:\\opencvStudy\\opencv_test\\TaskDemo\\TaskDemo\\save.jpg");
cvShowImage("saveimage",saveImge);
I met this:
Unhandled exception at 0x75709673 in TaskDemo.exe: Microsoft C++ exception: cv::Exception at memory location 0x0039ea0c..
Following is the whole program. Hope anyone could help me .Thanks very much
#include<opencv/cv.h>
#include<opencv/highgui.h>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/video/tracking.hpp"
#include <iostream>
#include <ctype.h>
CvPoint pt1 = cvPoint(0,0);
CvPoint pt2 = cvPoint(0,0);
bool is_selecting = false;
void cvMouseCallback(int mouseEvent,int x,int y,int flags,void* param)
{
switch(mouseEvent)
{
case CV_EVENT_LBUTTONDOWN:
pt1 = cvPoint(x,y);
pt2 = cvPoint(x,y);
is_selecting = true;
break;
case CV_EVENT_MOUSEMOVE:
if(is_selecting)
pt2 = cvPoint(x,y);
break;
case CV_EVENT_LBUTTONUP:
pt2 = cvPoint(x,y);
is_selecting = false;
break;
}
return;
}
int main(int argc,char* argv[])
{
char img_path[80] = "D:\\opencvStudy\\pic\\boldt.jpg";
char save_path[80] = "save.jpg";
char* window = "img";
IplImage* img = cvLoadImage(img_path);
IplImage* img_show = cvCloneImage(img);
cvNamedWindow(window,CV_WINDOW_AUTOSIZE);
cvSetMouseCallback(window,cvMouseCallback);
char text[80];
CvFont font;
cvInitFont(&font,CV_FONT_HERSHEY_PLAIN,1.0,1.0);
while(true)
{
cvCopy(img,img_show);
cvRectangle(img_show,pt1,pt2,cvScalar(255,255,255));
sprintf(text,"roi = cvRect(%d,%d,%d,%d)",pt1.x,pt1.y,std::abs(pt2.x-pt1.x),std::abs(pt2.y-pt1.y));
cvPutText(img_show,text,cvPoint(10,20),&font,cvScalar(0,0,255));
cvShowImage(window,img_show);
char key = cvWaitKey(10);
if (key='r')
{
cvSetImageROI(img,cvRect(pt1.x,pt1.y,std::abs(pt2.x-pt1.x),std::abs(pt2.y-pt1.y)));
cvSaveImage(save_path,img);
cvResetImageROI(img);
IplImage* saveImge = cvLoadImage("D:\\opencvStudy\\opencv_test\\TaskDemo\\TaskDemo\\save.jpg");
cvShowImage("saveimage",saveImge);
//cv::Mat saveImage=cv::imread("D:\\opencvStudy\\opencv_test\\TaskDemo\\TaskDemo\\save.jpg");
//cv::imshow("save",saveImage);
}
else if(key==27)
break;
}
cvReleaseImage(&img);
cvReleaseImage(&img_show);
return 0;
}
Update
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include <iostream>
#include <ctype.h>
using namespace std;
using namespace cv;
cv::Point pt1=Point(0,0);
cv::Point pt2=Point(0,0);
bool is_selecting=false;
static void onMouse(int mouseEvent,int x,int y,int flags,void* param)
{
switch(mouseEvent)
{
case CV_EVENT_LBUTTONDOWN://CV_EVENT_LBUTTONDOWN
pt1 = Point(x,y);
pt2 = Point(x,y);
is_selecting = true;
break;
case CV_EVENT_MOUSEMOVE:
if(is_selecting)
pt2 = Point(x,y);
break;
case CV_EVENT_LBUTTONUP:
pt2 = Point(x,y);
is_selecting = false;
break;
}
}
int main()
{
cv::Mat img=cv::imread("D:\\opencvStudy\\pic\\boldt.jpg");
cv::Mat img_show=img.clone();
cv::namedWindow("Task2",0);
cv::setMouseCallback("Task2",onMouse,0);
char text[80];
while(true)
{
img.copyTo(img_show);
cv::rectangle(img_show,pt1,pt2,cv::Scalar(255,255,255));
sprintf(text,"roi = cvRect(%d,%d,%d,%d)",pt1.x,pt1.y,std::abs(pt2.x-pt1.x),std::abs(pt2.y-pt1.y));
cv::putText(img_show,text,cvPoint(10,20),10,10,Scalar(0,0,255));
cv::imshow("Task2",img_show);
char key=cv::waitKey(10);
if (key='r')
{
cv::Mat save=img(cv::Rect(pt1.x,pt1.y,std::abs(pt2.x-pt1.x),std::abs(pt2.y-pt1.y)));
cv::imwrite("save.jpg",save);
cv::Mat saveImage=cv::imread("D:\\opencvStudy\\opencv_test\\TaskDemo\\TaskDemo\\save.jpg");
cv::imshow("save",saveImage);
}
else if(key==27)
break;
}
return 0;
}
The problem is with conflicting headers. You should not include old and new at the same time like this:
#include<opencv/cv.h>
#include<opencv/highgui.h>
#include "opencv2/highgui/highgui.hpp"
Instead, include the new headers only, like this:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
The reason for this is that the C++ headers also include the C interface.
UPDATE:
Of course if you use cv::Mat then you need to use the new functions for that as well.
CvCopy becomes cv::copy, there is no cvReleaseImage needed, cvRectangle becomes cv::rectangle, cvSetImageROI is img(rect), cvPoint becomes cv::Point cvRect becomes cv::Rect
cvCloneImage becomes img.clone() and so on...
Or you need some conversion from cv::Mat to IplImage to use the old functions. There are some questions on SO dealing with converting back-and-forth.
UPDATE2:
It is best to remove all cv:: since you are using using namespace cv.
Then check for functions and variables left with the old cv prefix, and remove those prefixes. (I've still found one: cvPoint).
Hang on, you are using char text[80]!
I think that is again a source of problems. It is best to switch it to
#include <sstream>
//...
stringstream ss;
ss << "Rect(" << pt1.x << ", " << ... << ")";
//...
putText(img_show, ss.str(), Point(10,20), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255) );
Note that the font (I use) is not 10, but FONT_HERSHEY_PLAIN (or some other FONT_ constant).

Resources