stringstream exits the program


4 posts
by Ginnychabada » Mon Jun 19, 2017 7:23 am
Hi, I have been trying to write a program to take continuous snaps on raspi camera. It worked all fine untill i included few other functions that are concerned with the unicorn hat. When i included them, it doesn't show any error during compiling or during run. It just comes out of the program without even printing the first printf statement in the program.


Here is the code before including the unicorn's related functions:
Code: Select all
#include <ctime>
#include <fstream>            
#include <sstream>            //stringstream - used for naming the files in the loop
#include <iostream>
#include <raspicam/raspicam.h>
#include <unistd.h>
#include <sys/time.h>
#include "shutter.h"

using namespace std;

int main (int argc, char **argv)
{
   bettercam Camera; //camera object
   
   //open camera
   if(!Camera.open())
   {
      cerr<<"Error opening the Camera"<<endl;
      return -1;
   }

   //shutter management
   int scale;
   cout<<endl<<" \t\t\t\t"<<"Enter the shutter speed in the range of 1 - 10: ";
   cin>>scale;   
   cout<<endl;
   Camera.chooseShutterspeed(scale);   

   
   
   for(int i=0;i<2;i++)
   {   

         //wait untill the camera stabilizes
         cout<<"Sleeping for 3 sec..."<<endl;
         sleep(3);

         struct timeval t1,t2;
         gettimeofday(&t1,NULL);            //timestamp 1
            //capture
            Camera.grab();
         gettimeofday(&t2,NULL);            //timestamp 2
      
         //allocate memory
         unsigned char *data=new unsigned char[  Camera.getImageTypeSize ( raspicam::RASPICAM_FORMAT_RGB )];
      
         //extract the image in rgb format
         Camera.retrieve ( data,raspicam::RASPICAM_FORMAT_RGB );//get camera image
      
           std::stringstream ss;
         //save
         ss<<"file-"<<i;
         
         std::string s = ss.str();
         std::ofstream outFile ( s.c_str(),std::ios::binary );
         outFile<<"P6\n"<<Camera.getWidth() <<" "<<Camera.getHeight() <<" 255\n";
         outFile.write ( ( char* ) data, Camera.getImageTypeSize ( raspicam::RASPICAM_FORMAT_RGB ) );
         cout<<"Image saved at "<<ss.str()<<endl;

         //time diff
         cout<<"Time diff: "<<t2.tv_usec-t1.tv_usec<<"micro seconds"<<endl<<endl<<endl;
      
         //free resrources   
         delete data;
   }

    return 0;
}





Here is the code after adding the other functionalities:
Code: Select all
#include <iostream>
#include <ctime>
#include <fstream>            
#include <sstream>            //stringstream - used for naming the files in the loop
#include <raspicam/raspicam.h>
#include <unistd.h>
#include <sys/time.h>
#include "shutter.h"


#include <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
#include <signal.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>

#include "ws2811.h"

using namespace std;

#define TARGET_FREQ    WS2811_TARGET_FREQ
#define GPIO_PIN       18
#define DMA            5

#define WIDTH          8
#define HEIGHT         8
#define LED_COUNT      (WIDTH * HEIGHT)
/*

ws2811_t ledstring
{
    .freq = TARGET_FREQ,
    .dmanum = DMA,
    .channel =
    {
        [0] =
        {
            .gpionum    = GPIO_PIN,
            .count      = LED_COUNT,
            .invert     = 0,
            .brightness = 55,
        }
    }
};
*/

void setBrightness(ws2811_t &ledstring,int b)
{
    ledstring.channel[0].brightness = b;
    return;
}

void setPixelColorRGB(ws2811_t &ledstring, int pixel, int r, int g, int b)
{
    ledstring.channel[0].leds[pixel] = (r << 16) | (g << 8) | b;
    return;
}

void clearLEDBuffer(ws2811_t &ledstring){
    int i;
    for(i=0; i<LED_COUNT;i++){
        setPixelColorRGB(ledstring, i,0,0,0);
    }
}

/*
  Remap an x/y coordinate to a pixel index
*/
int getPixelPosition(int x, int y){

    int map[8][8] = {
        {7 ,6 ,5 ,4 ,3 ,2 ,1 ,0 },
        {8 ,9 ,10,11,12,13,14,15},
        {23,22,21,20,19,18,17,16},
        {24,25,26,27,28,29,30,31},
        {39,38,37,36,35,34,33,32},
        {40,41,42,43,44,45,46,47},
        {55,54,53,52,51,50,49,48},
        {56,57,58,59,60,61,62,63}
    };

    return map[x][y];
}

void show(ws2811_t &ledstring){
    ws2811_render(&ledstring);
}

void unicorn_exit(int status){
    int i;
    ws2811_t ledstring;
    ledstring.freq = TARGET_FREQ;
    ledstring.dmanum = DMA;
    ledstring.channel[0].gpionum    = GPIO_PIN;
    ledstring.channel[0].count      = LED_COUNT;
    ledstring.channel[0].invert     = 0;
    ledstring.channel[0].brightness = 55;
    for (i = 0; i < 64; i++){
        setPixelColorRGB(ledstring, i,0,0,0);
    }
    ws2811_render(&ledstring);
    ws2811_fini(&ledstring);

    exit(status);
}

void control_led(ws2811_t &ledstring){
   int bri,p;
   cout<<"Enter the overall brightness of the LEDs\nNote: Brightness should be an integer ";
   cin>>bri;
   
   clearLEDBuffer(ledstring);
   show(ledstring);
   setBrightness(ledstring, bri);
   
   int n=-1;
    while(n<0){
        cout<<"\nEnter the number of LEDs to be turned ON at a time ";
        cin>>n;
   }
   
   int t=-1;
    while(t<0){
        cout<<"\nEnter the duration of ON in seconds ";
        cin>>t;
   }
   
   int x,y,r,g,b,i;
   
   for(i=0;i<n;i++){
      x=-1;y=-1;r=-1;g=-1;b=-1;
      while(x<0 || x>7){
         cout<<"Enter the x co-ordinate of led "<<i+1;
         cin>>x;
      }
      
      while(y<0 || y>7){
         cout<<"Enter the y co-ordinate of led "<<i+1;
         cin>>y;
      }
      
      cout<<"\n";
      while(r<0 || r>255){
         cout<<"Enter the value for R ";
         cin>>r;
      }
      
      while(g<0 || g>255){
         cout<<"Enter the value for G ";
         cin>>g;
      }
      
      while(b<0 || b>255){
         cout<<"Enter the value for B ";
         cin>>b;
      }
      cout<<"\n";
      p=getPixelPosition(x, y);
      setPixelColorRGB(ledstring, p, g, r, b);
   }
   show(ledstring);
   sleep(t);
}

int main()
{
   int i;
   ws2811_t ledstring;
    for (i = 0; i < 64; i++) {
        struct sigaction sa;
        memset(&sa, 0, sizeof(sa));
        sa.sa_handler = unicorn_exit;
        sigaction(i, &sa, NULL);
    }

    setvbuf(stdout, NULL, _IONBF, 0);

   
    ledstring.freq = TARGET_FREQ;
    ledstring.dmanum = DMA;
    ledstring.channel[0].gpionum    = GPIO_PIN;
    ledstring.channel[0].count      = LED_COUNT;
    ledstring.channel[0].invert     = 0;
    ledstring.channel[0].brightness = 55;

    if(ws2811_init(&ledstring))
    {
        return -1;
    }

    /////////////////////////////////////////////////// Camera Monitoring //////////////////////////////////////////////////
   

    //camera object
    bettercam Camera;

   //open camera
   if(!Camera.open())
   {
      cerr<<"Error opening the Camera"<<endl;
      return -1;
   }

   //shutter management
   int scale;
   cout<<endl<<" \t\t\t\t"<<"Enter the shutter speed in the range of 1 - 10: ";
   cin>>scale;   
   cout<<endl;
   Camera.chooseShutterspeed(scale);

   control_led(ledstring);

   for(int i=0;i<2;i++)
   {   

         //wait untill the camera stabilizes
         cout<<"Sleeping for 3 sec..."<<endl;
         sleep(3);

         struct timeval t1,t2;
         gettimeofday(&t1,NULL);            //timestamp 1
            //capture
            Camera.grab();
         gettimeofday(&t2,NULL);            //timestamp 2   

         //allocate memory
         unsigned char *data=new unsigned char[  Camera.getImageTypeSize ( raspicam::RASPICAM_FORMAT_RGB )];
      
         //extract the image in rgb format
         Camera.retrieve ( data,raspicam::RASPICAM_FORMAT_RGB );//get camera image
      
              std::stringstream ss;
         //save
         ss<<"file-"<<i;
         
         std::string s = ss.str();
         std::ofstream outFile ( s.c_str(),std::ios::binary );
         outFile<<"P6\n"<<Camera.getWidth() <<" "<<Camera.getHeight() <<" 255\n";
         outFile.write ( ( char* ) data, Camera.getImageTypeSize ( raspicam::RASPICAM_FORMAT_RGB ) );
         cout<<"Image saved at "<<ss.str()<<endl;

         time diff
         cout<<"Time diff: "<<t2.tv_usec-t1.tv_usec<<"micro seconds"<<endl<<endl<<endl;
      
         free resrources   
         delete data;
   }
 
   
   
     
   
   //unicorn_exit(0);
   clearLEDBuffer(ledstring);
   show(ledstring);
}




I guess the problem is with std::stringstream ss . I am not sure. Can someone tell me what's going wrong .
Posts: 13
Joined: Thu May 25, 2017 10:21 am
by LdB » Mon Jun 19, 2017 7:52 am
At a guess .. your if test is wrong
Code: Select all
if(ws2811_init(&ledstring))
    {
        return -1;
    }

Show us what ws2811_init does .. We don't have the code but that would do exactly as you say it does if wrong.
Posts: 301
Joined: Wed Dec 07, 2016 2:29 pm
by Paeryn » Mon Jun 19, 2017 11:20 am
I'm confused about the title, you say stringstream exits the program yet your old program uses stringstream and you say that works fine, none of the new code uses it so why do you suspect stringstream?

ws2811_init() returns 0 for success and -1 for failure so that part is ok. I'd stick a print there to see if that call is the one failing.

There is an issue with the exit handling function you set up (apart from that you try setting all signals from 0 to 63 to it).
Code: Select all
void unicorn_exit(int status){
    int i;
    ws2811_t ledstring;
    ledstring.freq = TARGET_FREQ;
    ledstring.dmanum = DMA;
    ledstring.channel[0].gpionum    = GPIO_PIN;
    ledstring.channel[0].count      = LED_COUNT;
    ledstring.channel[0].invert     = 0;
    ledstring.channel[0].brightness = 55;
    for (i = 0; i < 64; i++){
        setPixelColorRGB(ledstring, i,0,0,0);
    }
    ws2811_render(&ledstring);
    ws2811_fini(&ledstring);

    exit(status);
}

Here in your exit handler you for some reason create a new struct ws2811_t and try using it (and then finishing it) without ever initialising it. That isn't going to work (the struct holds information that it needs to talk to the hardware, this new one won't have that), you should be using & finishing the one that you originally created. And this handler could theoretically be called before the original struct has been initialised so you need to check for that.
She who travels light — forgot something.
User avatar
Posts: 1444
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England
by tommylee2k » Wed Jun 21, 2017 2:40 pm
It just comes out of the program without even printing the first printf statement in the program.


compile it with debugging info ( -g ), and see what happens in GDB
Posts: 12
Joined: Mon May 08, 2017 6:23 am