-
Test
04/15/2019 at 07:48 • 0 commentscheck out our test video
-
PCB
04/15/2019 at 07:45 • 0 commentsBesides the raspberry pi, we design the PCB to transfer data from sensor to pi.
-
utilize the ALSA lib
04/14/2019 at 22:16 • 0 commentsTo perform the music in raspberry pi, we apply the ALSA lib in linux to drive the raspi to play and control the music. Details are as following .
int main() { long loops; int rc; int size; snd_pcm_t *handle; snd_pcm_hw_params_t *params; unsigned int val; int dir; snd_pcm_uframes_t frames; char *buffer; /* Open PCM device for playback. */ rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (rc < 0) { fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); exit(1); } /* Allocate a hardware parameters object. */ snd_pcm_hw_params_alloca(¶ms); /* Fill it in with default values. */ snd_pcm_hw_params_any(handle, params); /* Set the desired hardware parameters. */ /* Interleaved mode */ snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); /* Signed 16-bit little-endian format */ snd_pcm_hw_params_set_format(handle, params, SND_PCM_FORMAT_S16_LE); /* Two channels (stereo) */ snd_pcm_hw_params_set_channels(handle, params, 2); /* 44100 bits/second sampling rate (CD quality) */ val = 44100; snd_pcm_hw_params_set_rate_near(handle, params, &val, &dir); /* Set period size to 32 frames. */ frames = 32; snd_pcm_hw_params_set_period_size_near(handle, params, &frames, &dir); /* Write the parameters to the driver */ rc = snd_pcm_hw_params(handle, params); if (rc < 0) { fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); exit(1); } /* Use a buffer large enough to hold one period */ snd_pcm_hw_params_get_period_size(params, &frames, &dir); size = frames * 4; /* 2 bytes/sample, 2 channels */ buffer = (char *) malloc(size); /* We want to loop for 5 seconds */ snd_pcm_hw_params_get_period_time(params, &val, &dir); /* 5 seconds in microseconds divided by * period time */ loops = 5000000 / val; while (1) { // loops--; // printf("%ld\n", loops); rc = read(0, buffer, size); /**/ if (rc == 0) { fprintf(stderr, "end of file on input\n"); break; } else if (rc != size) { fprintf(stderr, "short read: read %d bytes\n", rc); } rc = snd_pcm_writei(handle, buffer, frames); if (rc == -EPIPE) { /* EPIPE means underrun */ fprintf(stderr, "underrun occurred\n"); snd_pcm_prepare(handle); } else if (rc < 0) { fprintf(stderr, "error from writei: %s\n", snd_strerror(rc)); } else if (rc != (int)frames) { fprintf(stderr, "short write, write %d frames\n", rc); } /**/ } snd_pcm_drain(handle); snd_pcm_close(handle); free(buffer); return 0; }
-
add the subprocess function
04/14/2019 at 21:58 • 0 commentsTo play the music in the background, we add the subprocess function to call the music playback while the main function is still running to check the distance data from sensor in order to switch the music. when the distance reach the given range, the main function would create the subprocess to initial the music play thread.
class Popen { public: friend struct detail::ArgumentDeducer; friend class detail::Child; template <typename... Args> Popen(const std::string& cmd_args, Args&& ...args): args_(cmd_args) { vargs_ = util::split(cmd_args); init_args(std::forward<Args>(args)...); // Setup the communication channels of the Popen class stream_.setup_comm_channels(); if (!defer_process_start_) execute_process(); } template <typename... Args> Popen(std::initializer_list<const char*> cmd_args, Args&& ...args) { vargs_.insert(vargs_.end(), cmd_args.begin(), cmd_args.end()); init_args(std::forward<Args>(args)...); // Setup the communication channels of the Popen class stream_.setup_comm_channels(); if (!defer_process_start_) execute_process(); } void start_process() noexcept(false); int pid() const noexcept { return child_pid_; } int retcode() const noexcept { return retcode_; } int wait() noexcept(false); int poll() noexcept(false); // Does not fail, Caller is expected to recheck the // status with a call to poll() void kill(int sig_num = 9); void set_out_buf_cap(size_t cap) { stream_.set_out_buf_cap(cap); } void set_err_buf_cap(size_t cap) { stream_.set_err_buf_cap(cap); } int send(const char* msg, size_t length) { return stream_.send(msg, length); } int send(const std::vector<char>& msg) { return stream_.send(msg); } std::pair<OutBuffer, ErrBuffer> communicate(const char* msg, size_t length) { auto res = stream_.communicate(msg, length); retcode_ = wait(); return res; } std::pair<OutBuffer, ErrBuffer> communicate(const std::vector<char>& msg) { auto res = stream_.communicate(msg); retcode_ = wait(); return res; } std::pair<OutBuffer, ErrBuffer> communicate() { return communicate(nullptr, 0); } FILE* input() { return stream_.input(); } FILE* output() { return stream_.output();} FILE* error() { return stream_.error(); } /// Stream close APIs void close_input() { stream_.input_.reset(); } void close_output() { stream_.output_.reset(); } void close_error() { stream_.error_.reset(); } private: template <typename F, typename... Args> void init_args(F&& farg, Args&&... args); void init_args(); void populate_c_argv(); void execute_process() noexcept(false); private: detail::Streams stream_; bool defer_process_start_ = false; bool close_fds_ = false; bool has_preexec_fn_ = false; bool shell_ = false; bool session_leader_ = false; std::string exe_name_; std::string cwd_; std::map<std::string, std::string> env_; preexec_func preexec_fn_; // Command in string format std::string args_; // Comamnd provided as sequence std::vector<std::string> vargs_; std::vector<char*> cargv_; bool child_created_ = false; // Pid of the child process int child_pid_ = -1; int retcode_ = -1; }; inline void Popen::init_args() { populate_c_argv(); } template <typename F, typename... Args> inline void Popen::init_args(F&& farg, Args&&... args) { detail::ArgumentDeducer argd(this); argd.set_option(std::forward<F>(farg)); init_args(std::forward<Args>(args)...); } inline void Popen::populate_c_argv() { cargv_.clear(); cargv_.reserve(vargs_.size() + 1); for (auto& arg : vargs_) cargv_.push_back(&arg[0]); cargv_.push_back(nullptr); }
-
Fix bug that occupy CPU
04/14/2019 at 21:43 • 0 commentsWe come across the problem when the main program running, the switching music functions would get into dead state after being called some times. In the first, we thought the problem could in the music playback function or in creating too many subprocess without killing them when the function jump out. After we test the main function, we find the problem actually is in the communication between parent process and subprocess. So we fix it by adding poll function which would check whether the subprocess is running or not and stop sending signal to subprocess when it actually being killed.