I just started learning C++ this year. Currently, I'm using four accelerometers to calculate human body movement for my school project. I tried to use multi-thread but the data outputs are unstable as such when I tried multiple times, some of the data would change. It does give correct output data sometimes. The output is saved to Microsoft Excel while printing on the screen simultaneously. However, When I tried the accelerometer separately, it seems to work just fine. The output would change only when I multi-thread them together. I can't seem to find what cause the output data to change periodically. I appreciate any help I could get. Pardon my grammatical mistakes for it is not my native language. Thank you =D
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <process.h>
#include <Windows.h>
#include "erslib.h"
struct SENSOR_DATA {
int ID_1, ID_2, ID_3,ID_4;
int y_1, y_2, y_3, y_4;
int z_1, z_2, z_3, z_4;
int x_1, x_2, x_3, x_4;
};
void Thread_0(void);
void Thread_1(void);
void Thread_2(void);
void Thread_3(void);
FILE *fp[4];
errno_t err[4];
int key = 0;
int MainLoopFlag = true;
SENSOR_DATA acc;
int main()
{
DWORD ThreadID_0;
DWORD ThreadID_1;
DWORD ThreadID_2;
DWORD ThreadID_3;
HANDLE Handle_0 = NULL;
HANDLE Handle_1 = NULL;
HANDLE Handle_2 = NULL;
HANDLE Handle_3 = NULL;
Handle_0 = CreateThread(0,0,(LPTHREAD_START_ROUTINE) Thread_0, 0, 0, &ThreadID_0);
Sleep(1000);
Handle_1 = CreateThread(0,0,(LPTHREAD_START_ROUTINE) Thread_1, 0, 0, &ThreadID_1);
Sleep(1000);
Handle_2 = CreateThread(0,0,(LPTHREAD_START_ROUTINE) Thread_2, 0, 0, &ThreadID_2);
Sleep(1000);
Handle_3 = CreateThread(0,0,(LPTHREAD_START_ROUTINE) Thread_3, 0, 0, &ThreadID_3);
Sleep(1000);
WaitForSingleObject(Thread_0, INFINITE);
WaitForSingleObject(Thread_1, INFINITE);
WaitForSingleObject(Thread_2, INFINITE);
WaitForSingleObject(Thread_3, INFINITE);
//////Print and Data Output//////
while(MainLoopFlag){
if(_kbhit()){
key = _getch(); //a key to start data saving//
if(key == 'a' && Save_flag==0){
printf("Preparing for saving...\n");
Sleep(5000);
printf("Saving start\n");
char * fname_0 = ("C:\\Users\\Desktop\\adam\\ID 1\\test02.csv");
err[0] = fopen_s(&fp[0], fname_0,"w+");
if (fp[0]==NULL) {
printf("%s File cannot be opened。\n",fname_0);
return -1;
}
char * fname_1 = ("C:\\Users\\Desktop\\adam\\ID 2\\test02.csv");
err[1] = fopen_s(&fp[1], fname_1,"w+");
if (fp[1]==NULL) {
printf("%s File cannot be opened。\n",fname_1);
return -1;
}
char * fname_2 = ("C:\\Users\\Desktop\\adam\\ID 3\\test02.csv");
err[2] = fopen_s(&fp[2], fname_2,"w+");
if (fp[2]==NULL) {
printf("%s File cannot be opened。\n",fname_2);
return -1;
}
char * fname_3 = ("C:\\Users\\Desktop\\adam\\ID 4\\test02.csv");
err[3] = fopen_s(&fp[3], fname_3,"w+");
if (fp[3]==NULL) {
printf("%s File cannot be opened。\n",fname_3);
return -1;
}
Save_flag=1;
while(MainLoopFlag && Save_flag==1){
printf("ID->%d, x->%d, y->%d, z->%d \n",acc.ID_1,acc.x_1,acc.y_1,acc.z_1);
fprintf(fp[0],"%d, %d, %d, %d \n",acc.ID_1,acc.x_1,acc.y_1,acc.z_1);
printf("ID->%d, x->%d, y->%d, z->%d \n",acc.ID_2,acc.x_2,acc.y_2,acc.z_2);
fprintf(fp[1],"%d, %d, %d, %d \n",acc.ID_2,acc.x_2,acc.y_2,acc.z_2);
printf("ID->%d, x->%d, y->%d, z->%d \n",acc.ID_3,acc.x_3,acc.y_3,acc.z_3);
fprintf(fp[2],"%d, %d, %d, %d \n",acc.ID_3,acc.x_3,acc.y_3,acc.z_3);
printf("ID->%d, x->%d, y->%d, z->%d \n",acc.ID_4,acc.x_4,acc.y_4,acc.z_4);
fprintf(fp[3],"%d, %d, %d, %d \n",acc.ID_4,acc.x_4,acc.y_4,acc.z_4);
if(_kbhit()){
key = _getch();
//s key to stop data saving
if(key == 's' && Save_flag==1){
printf("End Data saving\n");
Save_flag=0;
fclose(fp[0]);
fclose(fp[1]);
fclose(fp[2]);
fclose(fp[3]);
MainLoopFlag = false;}
}
}
}
}
}
// Close Handle
CloseHandle(Handle_0);
CloseHandle(Handle_1);
CloseHandle(Handle_2);
CloseHandle(Handle_3);
return 0;
}
//--------------------------------------------------------------------------
// Name: Thread_1(void)
//--------------------------------------------------------------------------
void Thread_1(void)
{
unsigned char buf[4096];
unsigned char buf_data[4096];
unsigned char bin_data[5];
//unsigned char buf_str[4096];
int i,j,n;
int n_cou;
int ComPort = 20;
int flag=0;
int temp_char_1[7];
ERS_Open(ComPort,4096,4096);
ERS_Config(ComPort,ERS_38400|ERS_NO|ERS_1|ERS_8);
//最初に取得するデータは異常なので捨てる
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
// 1となる位置を調べる
flag=0;
while(MainLoopFlag){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++){
if((buf[i] & 0x80) == 0x80){
flag=1;
break;
}
}
if(flag==1)break;
Sleep(1);
}
// 1 となる位置から後ろをbuf_dataに入れる
n_cou = n - i;
for(j=0;j<n_cou;j++)
buf_data[j]=buf[i+j];
while(MainLoopFlag){
while(MainLoopFlag && n_cou<5){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++)buf_data[n_cou+i]=buf[i];
n_cou=n_cou+n;
}
for(i=0;i<5;i++)bin_data[i]=buf_data[i];
temp_char_1[0] = (bin_data[0] & 0x38) >> 3; //ID
acc.ID_2 = (int)temp_char_1[0];
temp_char_1[1] = (bin_data[0] & 0x07) << 7; // x = 3bit
temp_char_1[2] = (bin_data[1] & 0x38) << 4; // y = 3bit
temp_char_1[3] = (bin_data[1] & 0x07) << 7; // z = 3bit
temp_char_1[4] = (bin_data[2] & 0x7F) | temp_char_1[1];
acc.x_2 = (int)temp_char_1[4];
temp_char_1[5] = (bin_data[3] & 0x7F) | temp_char_1[2];
acc.y_2 = (int)temp_char_1[5];
temp_char_1[6] = (bin_data[4] & 0x7F) | temp_char_1[3];
acc.z_2 = (int)temp_char_1[6];
for(i=5;i<n_cou;i++)buf_data[i-5]=buf_data[i];
n_cou=n_cou-5;
}
ERS_CloseAll();
}
//--------------------------------------------------------------------------
// Name: Thread_2(void)
//--------------------------------------------------------------------------
void Thread_2(void)
{
unsigned char buf[4096];
unsigned char buf_data[4096];
unsigned char bin_data[5];
//unsigned char buf_str[4096];
int i,j,n;
int n_cou;
int ComPort = 15;
int flag=0;
int temp_char_2[7];
ERS_Open(ComPort,4096,4096);
ERS_Config(ComPort,ERS_38400|ERS_NO|ERS_1|ERS_8);
//最初に取得するデータは異常なので捨てる
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
// 1となる位置を調べる
flag=0;
while(MainLoopFlag){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++){
if((buf[i] & 0x80) == 0x80){
flag=1;
break;
}
}
if(flag==1)break;
Sleep(1);
}
// 1 となる位置から後ろをbuf_dataに入れる
n_cou = n - i;
for(j=0;j<n_cou;j++)
buf_data[j]=buf[i+j];
while(MainLoopFlag){
while(MainLoopFlag && n_cou<5){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++)buf_data[n_cou+i]=buf[i];
n_cou=n_cou+n;
}
for(i=0;i<5;i++)bin_data[i]=buf_data[i];
temp_char_2[0] = (bin_data[0] & 0x38) >> 3; //ID
acc.ID_3 = (int)temp_char_2[0];
temp_char_2[1] = (bin_data[0] & 0x07) << 7; // x = 3bit
temp_char_2[2] = (bin_data[1] & 0x38) << 4; // y = 3bit
temp_char_2[3] = (bin_data[1] & 0x07) << 7; // z = 3bit
temp_char_2[4] = (bin_data[2] & 0x7F) | temp_char_2[1];
acc.x_3 = (int)temp_char_2[4];
temp_char_2[5] = (bin_data[3] & 0x7F) | temp_char_2[2];
acc.y_3 = (int)temp_char_2[5];
temp_char_2[6] = (bin_data[4] & 0x7F) | temp_char_2[3];
acc.z_3 = (int)temp_char_2[6];
for(i=5;i<n_cou;i++)buf_data[i-5]=buf_data[i];
n_cou=n_cou-5;
}
ERS_CloseAll();
}
//--------------------------------------------------------------------------
// Name: Thread_3(void)
//--------------------------------------------------------------------------
void Thread_3(void)
{
unsigned char buf[4096];
unsigned char buf_data[4096];
unsigned char bin_data[5];
//unsigned char buf_str[4096];
int i,j,n;
int n_cou;
int ComPort = 3;
int flag=0;
int temp_char_3[7];
ERS_Open(ComPort,4096,4096);
ERS_Config(ComPort,ERS_38400|ERS_NO|ERS_1|ERS_8);
//最初に取得するデータは異常なので捨てる
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
// 1となる位置を調べる
flag=0;
while(MainLoopFlag){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++){
if((buf[i] & 0x80) == 0x80){
flag=1;
break;
}
}
if(flag==1)break;
Sleep(1);
}
// 1 となる位置から後ろをbuf_dataに入れる
n_cou = n - i;
for(j=0;j<n_cou;j++)
buf_data[j]=buf[i+j];
//for(i=0;i<n_cou;i++)printf("%x ",buf_data[i]);
//printf("\n");
while(MainLoopFlag){
while(MainLoopFlag && n_cou<5){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++)buf_data[n_cou+i]=buf[i];
n_cou=n_cou+n;
}
for(i=0;i<5;i++)bin_data[i]=buf_data[i];
//for(i=0;i<5;i++)printf("%x ",bin_data[i]);
//printf("\n");
temp_char_3[0] = (bin_data[0] & 0x38) >> 3; //ID
acc.ID_4 = (int)temp_char_3[0];
temp_char_3[1] = (bin_data[0] & 0x07) << 7; // x = 3bit
temp_char_3[2] = (bin_data[1] & 0x38) << 4; // y = 3bit
temp_char_3[3] = (bin_data[1] & 0x07) << 7; // z = 3bit
temp_char_3[4] = (bin_data[2] & 0x7F) | temp_char_3[1];
acc.x_4 = (int)temp_char_3[4];
temp_char_3[5] = (bin_data[3] & 0x7F) | temp_char_3[2];
acc.y_4 = (int)temp_char_3[5];
temp_char_3[6] = (bin_data[4] & 0x7F) | temp_char_3[3];
acc.z_4 = (int)temp_char_3[6];
for(i=5;i<n_cou;i++)buf_data[i-5]=buf_data[i];
n_cou=n_cou-5;
}
ERS_CloseAll();
}
Correct data :
(Example)
ID->1, x->47, y->147, z->298
ID->2, x->298, y->25, z->147
ID->3, x->47, y->147, z->298
ID->4, x->213, y->123, z->43
ID->1, x->49, y->152, z->222
ID->2, x->256, y->30, z->155
ID->3, x->47, y->147, z->298
ID->4, x->221, y->132, z->54
incorrect data:
ID->1, x->905, y->179, z->20
ID->6, x->47, y->147, z->298
ID->0, x->0, y->0, z->0
ID->4, x->1010, y->56, z->23
ID->1, x->905, y->179, z->20
ID->6, x->47, y->147, z->298
ID->0, x->0, y->0, z->0
ID->4, x->1010, y->56, z->23
Basically the ID shouldn't change while the x, y and z would as you move the accelerometer.
Related
Hello my goal is to design an embedded system for the Nios II processor and DE1-SoC development board that will control a servo motor to sweep between two angles. The embedded system should contain a custom IP that creates the appropriate Pulse-Width Modulation (PWM) signal to sweep the servo-motor’s arm. The system also contains 8 switches for entering the start and stop angles, 2 pushbuttons for “locking” in the angles and 5 seven-segment displays for displaying the start and stop angles. I am experimenting with the custom servo motor component in Nios and I am not sure how to proceed. I have made the component to accept inputs from the switches, but in previous trials I could not get the servo motor to move.
Any help would be appreciated
Here is my code:
#include "sys/alt_stdio.h"
#include "io.h"
#include <stdio.h>
#include "system.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "altera_avalon_pio_regs.h"
#define HEXZERO 0x40
#define HEXONE 0x79
#define HEXTWO 0x24
#define HEXTHREE 0x30
#define HEXFOUR 0x19
#define HEXFIVE 0x12
#define HEXSIX 0x02
#define HEXSEVEN 0x78
#define HEXEIGHT 0x00
#define HEXNINE 0x10
//array
char hexArray0 [] = { HEXZERO, HEXONE, HEXTWO, HEXTHREE, HEXFOUR, HEXFIVE, HEXSIX, HEXSEVEN, HEXEIGHT, HEXNINE };
char hexArray1 [] = { HEXZERO, HEXONE, HEXTWO, HEXTHREE, HEXFOUR, HEXFIVE, HEXSIX, HEXSEVEN, HEXEIGHT, HEXNINE };
char hexArray2 [] = { HEXZERO, HEXONE, HEXTWO, HEXTHREE, HEXFOUR, HEXFIVE, HEXSIX, HEXSEVEN, HEXEIGHT, HEXNINE };
char hexArray4 [] = { HEXZERO, HEXONE, HEXTWO, HEXTHREE, HEXFOUR, HEXFIVE, HEXSIX, HEXSEVEN, HEXEIGHT, HEXNINE };
char hexArray5 [] = { HEXZERO, HEXONE, HEXTWO, HEXTHREE, HEXFOUR, HEXFIVE, HEXSIX, HEXSEVEN, HEXEIGHT, HEXNINE };
// create standard embedded type definitions
typedef signed char sint8; // signed 8 bit values
typedef unsigned char uint8; // unsigned 8 bit values
typedef signed short sint16; // signed 16 bit values
typedef unsigned short uint16; // unsigned 16 bit values
typedef signed long sint32; // signed 32 bit values
typedef unsigned long uint32; // unsigned 32 bit values
typedef float real32; // 32 bit real values
//set up pointers to peripherals
//uint32* TimerPtr = (uint32*)TIMER_0_BASE;
uint32* JtagUartPtr = (uint32*)JTAG_UART_0_BASE;
uint32* CustomIpPtr = (uint32*)SERVO_CONTROLLER_0_BASE;
unsigned char* switchesBase_ptr = (unsigned char*)SWITCHES_BASE;
unsigned char* hex_ptr0 = (unsigned char*)HEX0_BASE;
unsigned char* hex_ptr1 = (unsigned char*)HEX1_BASE;
unsigned char* hex_ptr2 = (unsigned char*)HEX2_BASE;
unsigned char* hex_ptr4 = (unsigned char*)HEX4_BASE;
unsigned char* hex_ptr5 = (unsigned char*)HEX5_BASE;
unsigned char* buttons_ptr = (unsigned char*)PUSHBUTTONS_BASE;
int arrayCounter=0;
unsigned int read_push=0 ;
unsigned int read_switch=0 ;
unsigned int isr_flag=0 ; //if flag=0 means miniumum angle / flag=1 means maximum angle
int servo_input_min=0;
int servo_input_max=0;
int key3,key2 =0;
int hex0_index, hex1_index, hex2_index,hex4_index,hex5_index;
int fortySix= 0b00101110; //binary
int fortySix_n= 0x0000C57A; //fortySix*1099;
int oneThreeFour= 0b10000110; //binary
int oneThreeFour_n= 0x00018464; //oneThreeSix*742;
int eighty= 0b01010000; //binary
int eighty_n=0x00010F40; // eighty*868 ;
int hundred= 0b01100100; //binary
int hundred_n= 0x00013A74; //hundred*805;
int fortyFive= 0b00101101; //binary
int fortyFive_n= 0x0000C350 ;//fortyFive*1110;
int ninety= 0b01011010; //binary
int ninety_n=0x000124F8;// ninety* 833;
int oneThreeFive=0b10000111; //binary
int oneThreeFive_n= 0x000186A0; //oneThreeFive*740;
void button_isr(void *context)
/*****************************************************************************/
/* Interrupt Service Routine */
/* Determines what caused the interrupt and calls the appropriate */
/* subroutine. */
/* */
/*****************************************************************************/
{
unsigned char current_val;
//clear timer interrupt
//*TimerPtr = 0;
current_val= *buttons_ptr;
if(current_val==0b1000){
key3=1;
}
else if(current_val==0b0100){
key2=1;
}
*(buttons_ptr + 12)= 1;
return;
}
void servo_isr(void *context){
*(CustomIpPtr ) = servo_input_min;
*(CustomIpPtr + 1) = servo_input_max;
return;
}
int main()
{
printf("Hello from Nips II!\n");
uint32 i;
servo_input_min=fortyFive_n;
servo_input_max=oneThreeFive_n;
*hex_ptr0 = hexArray0[5]; //5
*hex_ptr1 = hexArray1[3]; //3
*hex_ptr2 = hexArray2[1]; //1
*hex_ptr4 = hexArray4[5]; //5
*hex_ptr5 = hexArray5[4]; //4
alt_ic_isr_register(SERVO_CONTROLLER_0_IRQ_INTERRUPT_CONTROLLER_ID, SERVO_CONTROLLER_0_IRQ, servo_isr,CustomIpPtr,0);
*(CustomIpPtr ) = servo_input_min;
*(CustomIpPtr + 1) = servo_input_max;
alt_ic_isr_register(PUSHBUTTONS_IRQ_INTERRUPT_CONTROLLER_ID,PUSHBUTTONS_IRQ,button_isr,0,0);
*(buttons_ptr + 8)= 0x0C; //key 3,2
while (1) { //start loop
*buttons_ptr &= 0x0C;
*switchesBase_ptr &= 0xFF;
read_push = *buttons_ptr;
read_switch = *switchesBase_ptr;
if (read_switch == fortySix) {
servo_input_min = fortySix_n;
isr_flag = 0; //key3
} else if (read_switch == oneThreeFour) {
servo_input_max = oneThreeFour_n;
isr_flag = 1; //key2
} else if (read_switch == eighty) {
servo_input_min = eighty_n;
isr_flag = 0; //key3
} else if (read_switch == hundred) {
servo_input_max = hundred_n;
isr_flag = 1; //key2
} else if (read_switch == ninety) {
servo_input_min = ninety_n;
servo_input_max = ninety_n;
isr_flag = 1; //key 3,2
}
if (isr_flag == 1 && key2 == 1) { //max angle
while (read_push == 13) { //while button is still pressed stay in loop
*buttons_ptr &= 0x0C;
read_push = *buttons_ptr;
}
if (servo_input_max == oneThreeFour_n) { //134
hex2_index = 1;
hex1_index = 3;
hex0_index = 4;
} else if (servo_input_max == hundred_n) { //100
hex2_index = 1;
hex1_index = 0;
hex0_index = 0;
} else if (servo_input_max == ninety_n) { //90
hex2_index = 9;
hex1_index = 0;
hex0_index = 0;
}
*hex_ptr2 = hexArray0[hex2_index];
*hex_ptr1 = hexArray0[hex1_index];
*hex_ptr0 = hexArray0[hex0_index];
while (read_push != 15) { //while button is still unpressed stay in loop 15=0
*buttons_ptr &= 0x0C;
read_push = *buttons_ptr;
}
} else if (isr_flag == 0 && key3 == 1) { //min angle
while (read_push != 13) { //while button is still unpressed stay in loop 15=0
*buttons_ptr &= 0x0C;
read_push = *buttons_ptr;
}
if (servo_input_max == fortySix_n) { //46
hex5_index = 4;
hex4_index = 6;
} else if (servo_input_max == eighty_n) { //80
hex5_index = 8;
hex4_index = 0;
} else if (servo_input_max == ninety_n) { //90
hex5_index = 9;
hex4_index = 0;
}
*hex_ptr5 = hexArray0[hex5_index];
*hex_ptr4 = hexArray0[hex4_index];
while (read_push != 15) { //while button is still unpressed stay in loop 15=0
*buttons_ptr &= 0x0C;
read_push = *buttons_ptr;
}
}
}
return 0;
}
I use lzmaspec.cpp from 7zip library lzma1900/cpp/7zip/Bundles/Lzmaspec to decompress lzma file.
it works fine and save file correctly.
when I take main2 function and and make header file to use it in my project,it does not save the whole file.
this is lzmaspec.h
/*
* LzmaSpec.h
*
* Created on: Oct 14, 2020
* Author: za2ponubuntu1844
*/
#ifndef LZMASPEC_H_
#define LZMASPEC_H_
int main2(const char *,const char *);
#endif /* LZMASPEC_H_ */
and this is my modified main2 function
/* LzmaSpec.cpp -- LZMA Reference Decoder
2015-06-14 : Igor Pavlov : Public domain */
// This code implements LZMA file decoding according to LZMA specification.
// This code is not optimized for speed.
#include <stdio.h>
#ifdef _MSC_VER
#pragma warning(disable : 4710) // function not inlined
#pragma warning(disable : 4996) // This function or variable may be unsafe
#endif
typedef unsigned char Byte;
typedef unsigned short UInt16;
#ifdef _LZMA_UINT32_IS_ULONG
typedef unsigned long UInt32;
#else
typedef unsigned int UInt32;
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 UInt64;
#else
typedef unsigned long long int UInt64;
#endif
struct CInputStream
{
FILE *File;
UInt64 Processed;
void Init() { Processed = 0; }
Byte ReadByte()
{
int c = getc(File);
if (c < 0)
throw "Unexpected end of file";
Processed++;
return (Byte)c;
}
};
struct COutStream
{
FILE *File;
UInt64 Processed;
void Init() { Processed = 0; }
void WriteByte(Byte b)
{
if (putc(b, File) == EOF)
throw "File writing error";
Processed++;
}
};
class COutWindow
{
Byte *Buf;
UInt32 Pos;
UInt32 Size;
bool IsFull;
public:
unsigned TotalPos;
COutStream OutStream;
COutWindow(): Buf(NULL) {}
~COutWindow() { delete []Buf; }
void Create(UInt32 dictSize)
{
Buf = new Byte[dictSize];
Pos = 0;
Size = dictSize;
IsFull = false;
TotalPos = 0;
}
void PutByte(Byte b)
{
TotalPos++;
Buf[Pos++] = b;
if (Pos == Size)
{
Pos = 0;
IsFull = true;
}
OutStream.WriteByte(b);
}
Byte GetByte(UInt32 dist) const
{
return Buf[dist <= Pos ? Pos - dist : Size - dist + Pos];
}
void CopyMatch(UInt32 dist, unsigned len)
{
for (; len > 0; len--)
PutByte(GetByte(dist));
}
bool CheckDistance(UInt32 dist) const
{
return dist <= Pos || IsFull;
}
bool IsEmpty() const
{
return Pos == 0 && !IsFull;
}
};
#define kNumBitModelTotalBits 11
#define kNumMoveBits 5
typedef UInt16 CProb;
#define PROB_INIT_VAL ((1 << kNumBitModelTotalBits) / 2)
#define INIT_PROBS(p) \
{ for (unsigned i = 0; i < sizeof(p) / sizeof(p[0]); i++) p[i] = PROB_INIT_VAL; }
class CRangeDecoder
{
UInt32 Range;
UInt32 Code;
void Normalize();
public:
CInputStream *InStream;
bool Corrupted;
bool Init();
bool IsFinishedOK() const { return Code == 0; }
UInt32 DecodeDirectBits(unsigned numBits);
unsigned DecodeBit(CProb *prob);
};
bool CRangeDecoder::Init()
{
Corrupted = false;
Range = 0xFFFFFFFF;
Code = 0;
Byte b = InStream->ReadByte();
for (int i = 0; i < 4; i++)
Code = (Code << 8) | InStream->ReadByte();
if (b != 0 || Code == Range)
Corrupted = true;
return b == 0;
}
#define kTopValue ((UInt32)1 << 24)
void CRangeDecoder::Normalize()
{
if (Range < kTopValue)
{
Range <<= 8;
Code = (Code << 8) | InStream->ReadByte();
}
}
UInt32 CRangeDecoder::DecodeDirectBits(unsigned numBits)
{
UInt32 res = 0;
do
{
Range >>= 1;
Code -= Range;
UInt32 t = 0 - ((UInt32)Code >> 31);
Code += Range & t;
if (Code == Range)
Corrupted = true;
Normalize();
res <<= 1;
res += t + 1;
}
while (--numBits);
return res;
}
unsigned CRangeDecoder::DecodeBit(CProb *prob)
{
unsigned v = *prob;
UInt32 bound = (Range >> kNumBitModelTotalBits) * v;
unsigned symbol;
if (Code < bound)
{
v += ((1 << kNumBitModelTotalBits) - v) >> kNumMoveBits;
Range = bound;
symbol = 0;
}
else
{
v -= v >> kNumMoveBits;
Code -= bound;
Range -= bound;
symbol = 1;
}
*prob = (CProb)v;
Normalize();
return symbol;
}
unsigned BitTreeReverseDecode(CProb *probs, unsigned numBits, CRangeDecoder *rc)
{
unsigned m = 1;
unsigned symbol = 0;
for (unsigned i = 0; i < numBits; i++)
{
unsigned bit = rc->DecodeBit(&probs[m]);
m <<= 1;
m += bit;
symbol |= (bit << i);
}
return symbol;
}
template <unsigned NumBits>
class CBitTreeDecoder
{
CProb Probs[(unsigned)1 << NumBits];
public:
void Init()
{
INIT_PROBS(Probs);
}
unsigned Decode(CRangeDecoder *rc)
{
unsigned m = 1;
for (unsigned i = 0; i < NumBits; i++)
m = (m << 1) + rc->DecodeBit(&Probs[m]);
return m - ((unsigned)1 << NumBits);
}
unsigned ReverseDecode(CRangeDecoder *rc)
{
return BitTreeReverseDecode(Probs, NumBits, rc);
}
};
#define kNumPosBitsMax 4
#define kNumStates 12
#define kNumLenToPosStates 4
#define kNumAlignBits 4
#define kStartPosModelIndex 4
#define kEndPosModelIndex 14
#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
#define kMatchMinLen 2
class CLenDecoder
{
CProb Choice;
CProb Choice2;
CBitTreeDecoder<3> LowCoder[1 << kNumPosBitsMax];
CBitTreeDecoder<3> MidCoder[1 << kNumPosBitsMax];
CBitTreeDecoder<8> HighCoder;
public:
void Init()
{
Choice = PROB_INIT_VAL;
Choice2 = PROB_INIT_VAL;
HighCoder.Init();
for (unsigned i = 0; i < (1 << kNumPosBitsMax); i++)
{
LowCoder[i].Init();
MidCoder[i].Init();
}
}
unsigned Decode(CRangeDecoder *rc, unsigned posState)
{
if (rc->DecodeBit(&Choice) == 0)
return LowCoder[posState].Decode(rc);
if (rc->DecodeBit(&Choice2) == 0)
return 8 + MidCoder[posState].Decode(rc);
return 16 + HighCoder.Decode(rc);
}
};
unsigned UpdateState_Literal(unsigned state)
{
if (state < 4) return 0;
else if (state < 10) return state - 3;
else return state - 6;
}
unsigned UpdateState_Match (unsigned state) { return state < 7 ? 7 : 10; }
unsigned UpdateState_Rep (unsigned state) { return state < 7 ? 8 : 11; }
unsigned UpdateState_ShortRep(unsigned state) { return state < 7 ? 9 : 11; }
#define LZMA_DIC_MIN (1 << 12)
class CLzmaDecoder
{
public:
CRangeDecoder RangeDec;
COutWindow OutWindow;
bool markerIsMandatory;
unsigned lc, pb, lp;
UInt32 dictSize;
UInt32 dictSizeInProperties;
void DecodeProperties(const Byte *properties)
{
unsigned d = properties[0];
if (d >= (9 * 5 * 5))
throw "Incorrect LZMA properties";
lc = d % 9;
d /= 9;
pb = d / 5;
lp = d % 5;
dictSizeInProperties = 0;
for (int i = 0; i < 4; i++)
dictSizeInProperties |= (UInt32)properties[i + 1] << (8 * i);
dictSize = dictSizeInProperties;
if (dictSize < LZMA_DIC_MIN)
dictSize = LZMA_DIC_MIN;
}
CLzmaDecoder(): LitProbs(NULL) {}
~CLzmaDecoder() { delete []LitProbs; }
void Create()
{
OutWindow.Create(dictSize);
CreateLiterals();
}
int Decode(bool unpackSizeDefined, UInt64 unpackSize);
private:
CProb *LitProbs;
void CreateLiterals()
{
LitProbs = new CProb[(UInt32)0x300 << (lc + lp)];
}
void InitLiterals()
{
UInt32 num = (UInt32)0x300 << (lc + lp);
for (UInt32 i = 0; i < num; i++)
LitProbs[i] = PROB_INIT_VAL;
}
void DecodeLiteral(unsigned state, UInt32 rep0)
{
unsigned prevByte = 0;
if (!OutWindow.IsEmpty())
prevByte = OutWindow.GetByte(1);
unsigned symbol = 1;
unsigned litState = ((OutWindow.TotalPos & ((1 << lp) - 1)) << lc) + (prevByte >> (8 - lc));
CProb *probs = &LitProbs[(UInt32)0x300 * litState];
if (state >= 7)
{
unsigned matchByte = OutWindow.GetByte(rep0 + 1);
do
{
unsigned matchBit = (matchByte >> 7) & 1;
matchByte <<= 1;
unsigned bit = RangeDec.DecodeBit(&probs[((1 + matchBit) << 8) + symbol]);
symbol = (symbol << 1) | bit;
if (matchBit != bit)
break;
}
while (symbol < 0x100);
}
while (symbol < 0x100)
symbol = (symbol << 1) | RangeDec.DecodeBit(&probs[symbol]);
OutWindow.PutByte((Byte)(symbol - 0x100));
}
CBitTreeDecoder<6> PosSlotDecoder[kNumLenToPosStates];
CBitTreeDecoder<kNumAlignBits> AlignDecoder;
CProb PosDecoders[1 + kNumFullDistances - kEndPosModelIndex];
void InitDist()
{
for (unsigned i = 0; i < kNumLenToPosStates; i++)
PosSlotDecoder[i].Init();
AlignDecoder.Init();
INIT_PROBS(PosDecoders);
}
unsigned DecodeDistance(unsigned len)
{
unsigned lenState = len;
if (lenState > kNumLenToPosStates - 1)
lenState = kNumLenToPosStates - 1;
unsigned posSlot = PosSlotDecoder[lenState].Decode(&RangeDec);
if (posSlot < 4)
return posSlot;
unsigned numDirectBits = (unsigned)((posSlot >> 1) - 1);
UInt32 dist = ((2 | (posSlot & 1)) << numDirectBits);
if (posSlot < kEndPosModelIndex)
dist += BitTreeReverseDecode(PosDecoders + dist - posSlot, numDirectBits, &RangeDec);
else
{
dist += RangeDec.DecodeDirectBits(numDirectBits - kNumAlignBits) << kNumAlignBits;
dist += AlignDecoder.ReverseDecode(&RangeDec);
}
return dist;
}
CProb IsMatch[kNumStates << kNumPosBitsMax];
CProb IsRep[kNumStates];
CProb IsRepG0[kNumStates];
CProb IsRepG1[kNumStates];
CProb IsRepG2[kNumStates];
CProb IsRep0Long[kNumStates << kNumPosBitsMax];
CLenDecoder LenDecoder;
CLenDecoder RepLenDecoder;
void Init()
{
InitLiterals();
InitDist();
INIT_PROBS(IsMatch);
INIT_PROBS(IsRep);
INIT_PROBS(IsRepG0);
INIT_PROBS(IsRepG1);
INIT_PROBS(IsRepG2);
INIT_PROBS(IsRep0Long);
LenDecoder.Init();
RepLenDecoder.Init();
}
};
#define LZMA_RES_ERROR 0
#define LZMA_RES_FINISHED_WITH_MARKER 1
#define LZMA_RES_FINISHED_WITHOUT_MARKER 2
int CLzmaDecoder::Decode(bool unpackSizeDefined, UInt64 unpackSize)
{
if (!RangeDec.Init())
return LZMA_RES_ERROR;
Init();
UInt32 rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
unsigned state = 0;
for (;;)
{
if (unpackSizeDefined && unpackSize == 0 && !markerIsMandatory)
if (RangeDec.IsFinishedOK())
return LZMA_RES_FINISHED_WITHOUT_MARKER;
unsigned posState = OutWindow.TotalPos & ((1 << pb) - 1);
if (RangeDec.DecodeBit(&IsMatch[(state << kNumPosBitsMax) + posState]) == 0)
{
if (unpackSizeDefined && unpackSize == 0)
return LZMA_RES_ERROR;
DecodeLiteral(state, rep0);
state = UpdateState_Literal(state);
unpackSize--;
continue;
}
unsigned len;
if (RangeDec.DecodeBit(&IsRep[state]) != 0)
{
if (unpackSizeDefined && unpackSize == 0)
return LZMA_RES_ERROR;
if (OutWindow.IsEmpty())
return LZMA_RES_ERROR;
if (RangeDec.DecodeBit(&IsRepG0[state]) == 0)
{
if (RangeDec.DecodeBit(&IsRep0Long[(state << kNumPosBitsMax) + posState]) == 0)
{
state = UpdateState_ShortRep(state);
OutWindow.PutByte(OutWindow.GetByte(rep0 + 1));
unpackSize--;
continue;
}
}
else
{
UInt32 dist;
if (RangeDec.DecodeBit(&IsRepG1[state]) == 0)
dist = rep1;
else
{
if (RangeDec.DecodeBit(&IsRepG2[state]) == 0)
dist = rep2;
else
{
dist = rep3;
rep3 = rep2;
}
rep2 = rep1;
}
rep1 = rep0;
rep0 = dist;
}
len = RepLenDecoder.Decode(&RangeDec, posState);
state = UpdateState_Rep(state);
}
else
{
rep3 = rep2;
rep2 = rep1;
rep1 = rep0;
len = LenDecoder.Decode(&RangeDec, posState);
state = UpdateState_Match(state);
rep0 = DecodeDistance(len);
if (rep0 == 0xFFFFFFFF)
return RangeDec.IsFinishedOK() ?
LZMA_RES_FINISHED_WITH_MARKER :
LZMA_RES_ERROR;
if (unpackSizeDefined && unpackSize == 0)
return LZMA_RES_ERROR;
if (rep0 >= dictSize || !OutWindow.CheckDistance(rep0))
return LZMA_RES_ERROR;
}
len += kMatchMinLen;
bool isError = false;
if (unpackSizeDefined && unpackSize < len)
{
len = (unsigned)unpackSize;
isError = true;
}
OutWindow.CopyMatch(rep0 + 1, len);
unpackSize -= len;
if (isError)
return LZMA_RES_ERROR;
}
}
static void Print(const char *s)
{
fputs(s, stdout);
}
static void PrintError(const char *s)
{
fputs(s, stderr);
}
#define CONVERT_INT_TO_STR(charType, tempSize) \
void ConvertUInt64ToString(UInt64 val, char *s)
{
char temp[32];
unsigned i = 0;
while (val >= 10)
{
temp[i++] = (char)('0' + (unsigned)(val % 10));
val /= 10;
}
*s++ = (char)('0' + (unsigned)val);
while (i != 0)
{
i--;
*s++ = temp[i];
}
*s = 0;
}
void PrintUInt64(const char *title, UInt64 v)
{
Print(title);
Print(" : ");
char s[32];
ConvertUInt64ToString(v, s);
Print(s);
Print(" bytes \n");
}
int main2(const char * infile, const char *outfile)
{
try
{
Print("\nLZMA Reference Decoder 15.00 : Igor Pavlov : Public domain : 2015-04-16\n");
//if (numArgs == 1)
// Print("\nUse: lzmaSpec a.lzma outFile");
//if (numArgs != 3)
// throw "you must specify two parameters";
CInputStream inStream;
inStream.File = fopen(infile, "rb");
inStream.Init();
if (inStream.File == 0)
throw "Can't open input file";
CLzmaDecoder lzmaDecoder;
lzmaDecoder.OutWindow.OutStream.File = fopen(outfile, "wb+");
lzmaDecoder.OutWindow.OutStream.Init();
if (inStream.File == 0)
throw "Can't open output file";
Byte header[13];
int i;
for (i = 0; i < 13; i++)
header[i] = inStream.ReadByte();
lzmaDecoder.DecodeProperties(header);
printf("\nlc=%d, lp=%d, pb=%d", lzmaDecoder.lc, lzmaDecoder.lp, lzmaDecoder.pb);
printf("\nDictionary Size in properties = %u", lzmaDecoder.dictSizeInProperties);
printf("\nDictionary Size for decoding = %u", lzmaDecoder.dictSize);
UInt64 unpackSize = 0;
bool unpackSizeDefined = false;
for (i = 0; i < 8; i++)
{
Byte b = header[5 + i];
if (b != 0xFF)
unpackSizeDefined = true;
unpackSize |= (UInt64)b << (8 * i);
}
lzmaDecoder.markerIsMandatory = !unpackSizeDefined;
Print("\n");
if (unpackSizeDefined)
PrintUInt64("Uncompressed Size", unpackSize);
else
Print("End marker is expected\n");
lzmaDecoder.RangeDec.InStream = &inStream;
Print("\n");
lzmaDecoder.Create();
int res = lzmaDecoder.Decode(unpackSizeDefined, unpackSize);
PrintUInt64("Read ", inStream.Processed);
PrintUInt64("Written ", lzmaDecoder.OutWindow.OutStream.Processed);
if (res == LZMA_RES_ERROR)
throw "LZMA decoding error";
else if (res == LZMA_RES_FINISHED_WITHOUT_MARKER)
Print("Finished without end marker");
else if (res == LZMA_RES_FINISHED_WITH_MARKER)
{
if (unpackSizeDefined)
{
if (lzmaDecoder.OutWindow.OutStream.Processed != unpackSize)
throw "Finished with end marker before than specified size";
Print("Warning: ");
}
Print("Finished with end marker");
}
else
throw "Internal Error";
Print("\n");
if (lzmaDecoder.RangeDec.Corrupted)
{
Print("\nWarning: LZMA stream is corrupted\n");
}
//15-10-2020
}
catch (const char *s)
{
PrintError("\nError:\n");
PrintError(s);
PrintError("\n");
return 1;
}
catch(...)
{
PrintError("\nError\n");
return 1;
}
return 0;
}
/*
int
#ifdef _MSC_VER
__cdecl
#endif
main(int numArgs, const char *args[])
{
try { return main2(numArgs, args); }
catch (const char *s)
{
PrintError("\nError:\n");
PrintError(s);
PrintError("\n");
return 1;
}
catch(...)
{
PrintError("\nError\n");
return 1;
}
}
*/
when i debug it i find that function
void WriteByte(Byte b)
works fine but the resulting file does not have correct size.
i used this file
13h_ticks.bi5 from dukascopy
i uploaded it here
https://github.com/ahmed-allam/starting_coding
I do not know why this happens.
when i try to decompress same file using lzmaspec.cpp outside project ,it works fine.
I need guide line where the error could be?
I'm trying to program a class to control the MPU6050 with the Arduino Wire library but when I run the code in my Arduino mini it freezes after a few seconds.
There is the code of the library and a test sketch:
// Include Wire Library for I2C
#include <Wire.h>
enum MPU6050_filter {_256Hz, _188Hz, _98Hz, _42Hz, _20Hz, _10Hz, _5Hz};
enum MPU6050_gyro {_250dps, _500dps, _1000dps, _2000dps};
enum MPU6050_accel {_2g, _4g, _8g, _16Hz};
class MPU6050
{
public:
MPU6050 ();
bool start (bool AD0_value);
void goToSleep ();
void stopSleeping ();
void setFilterVal (MPU6050_filter filter_val);
void setGyroRange (MPU6050_gyro range);
void setAccelRange (MPU6050_accel range);
bool dataAvailable ();
void getLastGyroData (float& gx, float& gy, float& gz);
void getRawGyroData (int& gx, int& gy, int& gz);
private:
void writeRegister (byte address, byte data);
byte readRegister (byte address);
void readData (byte start_address, byte bytes, byte* data);
float convertGyroToDPS (int gyro);
bool AD0_val;
MPU6050_filter filter;
MPU6050_accel accel_range;
MPU6050_gyro gyro_range;
unsigned long last_read;
const unsigned long min_read_time = 1;
};
MPU6050::MPU6050 () : AD0_val(false),
filter(_256Hz),
accel_range(_2g),
gyro_range(_250dps) {}
bool MPU6050::start (bool AD0_value)
{
AD0_val = AD0_value;
// init sample rate div to 0 (max sample rate)
writeRegister(0x19, 0);
// activate FIFO for gyroscope data
writeRegister(0x23, 0x70);
// clear config setup register
writeRegister(0x6B, 0);
// setup the register
writeRegister(0x37, 0x10);
// set interrupt by data ready
writeRegister(0x38, 0x01);
}
void MPU6050::goToSleep ()
{
byte prev_data = readRegister(0x6B);
prev_data = (prev_data | 0x40);
writeRegister(0x6B, prev_data);
}
void MPU6050::stopSleeping ()
{
byte prev_data = readRegister(0x6B);
prev_data = (prev_data & 0xBF);
writeRegister(0x6B, prev_data);
}
void MPU6050::setFilterVal (MPU6050_filter filter_val)
{
int val;
if (filter_val == _256Hz) val = 0;
else if (filter_val == _188Hz) val = 1;
else if (filter_val == _98Hz) val = 2;
else if (filter_val == _42Hz) val = 3;
else if (filter_val == _20Hz) val = 4;
else if (filter_val == _10Hz) val = 5;
else val = 6;
byte data = readRegister(0x1A);
data = (data & 0xF8) | (val & 0x07);
writeRegister(0x1A, data);
filter = filter_val;
}
void MPU6050::setAccelRange (MPU6050_accel range)
{
byte value;
if (range == _2g) value = 0;
else if (range == _4g) value = 1;
else if (range == _8g) value = 2;
else value = 3;
byte reg_value = readRegister(0x1C);
reg_value = (reg_value & 0xE0) | (value << 3);
writeRegister(0x1C, reg_value);
accel_range = range;
}
void MPU6050::setGyroRange (MPU6050_gyro range)
{
byte value;
if (range == _250dps) value = 0;
else if (range == _500dps) value = 1;
else if (range == _1000dps) value = 2;
else value = 3;
byte reg_value = readRegister(0x1B);
reg_value = (reg_value & 0xE0) | (value << 3);
writeRegister(0x1B, reg_value);
gyro_range = range;
}
bool MPU6050::dataAvailable ()
{
return (readRegister(0x3A) & 0x01);
}
void MPU6050::getLastGyroData (float& gx, float& gy, float& gz)
{
int raw_x, raw_y, raw_z;
getRawGyroData(raw_x, raw_y, raw_z);
gx = convertGyroToDPS(raw_x);
gy = convertGyroToDPS(raw_y);
gz = convertGyroToDPS(raw_z);
}
void MPU6050::getRawGyroData (int& gx, int& gy, int& gz)
{
byte* data = new byte[6];
readData(0x43, 6, data);
gx = data[0] << 8 | data[1];
gy = data[2] << 8 | data[3];
gz = data[4] << 8 | data[5];
delete data;
}
void MPU6050::writeRegister (byte address, byte data)
{
Wire.beginTransmission(0x68 + AD0_val);
Wire.write(address);
Wire.write(data);
Wire.endTransmission();
}
byte MPU6050::readRegister (byte address)
{
byte data_buff = 0x00;
Wire.beginTransmission(byte(0x68 + AD0_val));
//Send the requested starting register
Wire.write(address);
//End the transmission
Wire.endTransmission(false);
//Request 14 bytes from the MPU-6050
Wire.requestFrom(byte(0x68 + AD0_val), byte(0x01), byte(true));
unsigned long initial_time = millis();
//Wait until all the bytes are received
while(Wire.available() == 0 and millis() < initial_time + 5);
if (millis() < initial_time + 5)
{
// read the data
data_buff = Wire.read();
}
// end the transmission
Wire.endTransmission();
return data_buff;
}
void MPU6050::readData (byte start_address, byte bytes, byte* data)
{
Wire.beginTransmission(byte(0x68 + AD0_val));
//Send the requested starting register
Wire.write(start_address);
//End the transmission
Wire.endTransmission(false);
//Request 14 bytes from the MPU-6050
Wire.requestFrom(byte(0x68 + AD0_val), bytes, byte(true));
//Wait until all the bytes are received
while(Wire.available() < bytes);
for (int i = 0; i < bytes; i++)
data[i] = Wire.read();
Wire.endTransmission();
}
float MPU6050::convertGyroToDPS (int gyro)
{
if (gyro_range == _250dps) return float(gyro)/131.0;
else if (gyro_range == _500dps) return float(gyro)/65.5;
else if (gyro_range == _1000dps) return float(gyro)/32.8;
else return float(gyro)/16.4;
}
#define SHOW_EACH 50
MPU6050 chip;
unsigned long last_shown = 0;
unsigned this_fps = 0;
unsigned last_fps = 0;
unsigned last_time = 0;
unsigned total_fps = 0;
float g_x, g_y, g_z;
void setup()
{
Serial.begin(115200);
Serial.println("--------");
chip.setFilterVal(_256Hz);
chip.setGyroRange(_250dps);
chip.start(false);
}
void loop()
{
if (chip.dataAvailable())
chip.getLastGyroData(g_x, g_y, g_z);
++this_fps;
++total_fps;
if (millis()/1000 != last_time)
{
last_time = millis()/1000;
last_fps = this_fps;
this_fps = 0;
}
if (millis() - last_shown >= SHOW_EACH)
{
last_shown = millis();
Serial.print(g_x);
Serial.print(" ");
Serial.print(g_y);
Serial.print(" ");
Serial.print(g_y);
Serial.print(" ");
Serial.print(last_fps);
Serial.print(" ");
Serial.println(total_fps);
}
}
Some testing with Serial.println points to the function requestFrom from the Wire library. What can be the cause?
Sorry that i write this as an answer, but I can't write comments yet.
1st. There are multiple requestFrom() calls in your code, so it would be better to specify where does the problem occure exactly (if you can).
2nd. Are you completely sure that, it's the requestFrom() where your code hang. In readData() there is a while() just after requestFrom(). Maybe it hangs there, as the other device don't send enough bytes (for some reasons).
Anyway this might help a litle (link), here they recommend to always check the return value of endTransmission().
Hi i am trying to record from a board and i have successfully record 4 seconds. Problem is when i try to record for more time, i got an error telling me that there not enough memory. my target is to record a 5 minutes file. Until now i have create a buffer named snIn[256] where are the samples. i send it to a big buffer of [16K * 4sec] and when it is full, i create the wav file.
#include "SAI_InOut.hpp"
#include "F746_GUI.hpp"
#include "Delay.hpp"
#include "WaveformDisplay.hpp"
#include "SDFileSystem.h"
#include "wavfile.h"
using namespace Mikami;
#define RES_STR_SIZE 0x20
#define WAVFILE_SAMPLES_PER_SECOND 16000
#define REC_TIME 4
//Create an SDFileSystem object
SDFileSystem sd("sd");
bool flag = 1;
int count = 0;
char *res_buf;
int rp = 0;
const int NUM_SAMPLES = WAVFILE_SAMPLES_PER_SECOND * REC_TIME;
Array<int16_t> my_buffer(NUM_SAMPLES);
int j = 0;
static const char *target_filename = "/sd/rectest.wav";
const int SEG_SIZE = 256;
int sent_array = 0;
int rec(const char *filename, Array<int16_t> my_buffer)
{
j = 0;
flag = 0;
sent_array = 0;
WavFileResult result;
wavfile_info_t info;
wavfile_data_t data;
WAVFILE_INFO_AUDIO_FORMAT(&info) = 1;
WAVFILE_INFO_NUM_CHANNELS(&info) = 1;
WAVFILE_INFO_SAMPLE_RATE(&info) = WAVFILE_SAMPLES_PER_SECOND;
WAVFILE_INFO_BITS_PER_SAMPLE(&info) = 16;
WAVFILE_INFO_BYTE_RATE(&info) = WAVFILE_INFO_NUM_CHANNELS(&info) * WAVFILE_INFO_SAMPLE_RATE(&info) * (WAVFILE_INFO_BITS_PER_SAMPLE(&info) / 8);
WAVFILE_INFO_BLOCK_ALIGN(&info) = 2;
WAVFILE *wf = wavfile_open(filename, WavFileModeWrite, &result);
if (result != WavFileResultOK) {
wavfile_result_string(result, res_buf, RES_STR_SIZE);
printf("%s", res_buf);
return result;
} else printf ("Open file success \r\n");
rp = 0;
WAVFILE_DATA_NUM_CHANNELS(&data) = 1;
result = wavfile_write_info(wf, &info);
if (result != WavFileResultOK) {
wavfile_result_string(result, res_buf, RES_STR_SIZE);
printf("%s", res_buf);
return result; } else printf ("Write info success \r\n");
while ( rp < NUM_SAMPLES ) {
WAVFILE_DATA_CHANNEL_DATA(&data, 0) = my_buffer[rp];
result = wavfile_write_data(wf, &data);
rp += 1;
}
if (result != WavFileResultOK) {
wavfile_result_string(result, res_buf, RES_STR_SIZE);
printf("%s", res_buf);
return result; } else printf ("Write Data file success \r\n");
result = wavfile_close(wf);
if (result != WavFileResultOK) {
wavfile_result_string(result, res_buf , RES_STR_SIZE);
printf("%s", res_buf);
return result; } else printf ("Close file success \r\n");
//UnMount the filesystem
sd.unmount();
printf("Success rec !\r\n");
return 0;
}
int main()
{
//Mount the filesystem
sd.mount();
const float MAX_DELAY = 0.5f; // 最大遅延,単位:秒
const int FS = I2S_AUDIOFREQ_16K; // 標本化周波数: 16 kHz
const uint32_t MAX_ARRAY_SIZE = (uint32_t)(MAX_DELAY*FS);
SaiIO mySai(SaiIO::BOTH, 256, FS, INPUT_DEVICE_DIGITAL_MICROPHONE_2);
Label myLabel(185, 10, "Delay System", Label::CENTER, Font16);
// ButtonGroup: "ON", "OFF"
const uint16_t BG_LEFT = 370;
const uint16_t BG_WIDTH = 100;
const uint16_t BG_HEIGHT = 45;
ButtonGroup onOff(BG_LEFT, 40, BG_WIDTH/2, BG_HEIGHT,
2, (string[]){"ON", "OFF"}, 0, 0, 2, 1);
const uint16_t SB_LEFT = BG_LEFT - 320;
const uint16_t SB_WIDTH = 270;
const uint16_t SB_Y0 = 240;
char str[20];
sprintf(str, " %3.1f [s]", MAX_DELAY);
SeekBar barDelay(SB_LEFT, SB_Y0, SB_WIDTH,
0, MAX_ARRAY_SIZE, 0, "0", "", str);
NumericLabel<float> labelDelay(SB_LEFT+SB_WIDTH/2, SB_Y0-40, "DELEY: %4.2f", 0, Label::CENTER);
DelaySystem delaySystem(MAX_ARRAY_SIZE);
WaveformDisplay displayIn(*GuiBase::GetLcdPtr(), SB_LEFT+7, 70, 256, 9,LCD_COLOR_WHITE, LCD_COLOR_CYAN,GuiBase::ENUM_BACK);
Label inLabel(SB_LEFT-30, 65, "IN");
WaveformDisplay displayOut(*GuiBase::GetLcdPtr(), SB_LEFT+7, 130, 256, 9,LCD_COLOR_WHITE, LCD_COLOR_CYAN,GuiBase::ENUM_BACK);
Label outLabel(SB_LEFT-30, 125, "OUT");
int runStop = 1;
Array<int16_t> snIn(mySai.GetLength());
Array<int16_t> snOut(mySai.GetLength());
mySai.RecordIn();
mySai.PlayOut();
mySai.PauseOut();
while (true)
{
// On/OFF
int num;
if (onOff.GetTouchedNumber(num))
if (runStop != num)
{
if (num == 0) mySai.ResumeOut();
else mySai.PauseOut();
runStop = num;
}
if (mySai.IsCompleted())
{
for (int n=0; n<mySai.GetLength() ; n++)
{
int16_t xL, xR;
mySai.Input(xL,xR);
int16_t xn = xL + xR;
snIn[n] = xn;
my_buffer[j] = xn;
j++;
if (j == NUM_SAMPLES && flag == 1) {
rec (target_filename , my_buffer); }
int16_t yn = delaySystem.Execute(xn);
mySai.Output(yn, yn);
snOut[n] = yn;
}
mySai.Reset();
displayIn.Execute(snIn);
}
}
}
I thought about a possible solution, to fill directly the "data field" of the wavefile with the snIn[256] buffer (instead of using my_buffer) again and again and at the end close the wavfile. Please let me know what you think about that and other solutions
things to note: 1) while a write operation is being performed, more data is still coming in.
At the very least I would double buffer that data, so can be writing one buffer while the other one fills.
Usually this means using an interrupt to collect the samples (into which ever buffer is currently being filed.)
the foreground program waits for the current buffer to be 'full', then initiates write operation.,
then waits again for a buffer to be 'full'
The interrupt function tracks which buffer is being filled and the current index into that buffer. When a buffer is full, set a 'global' status to let the foreground program know which buffer is ready to be written.
The foreground program writes the buffer, then resets the status for that buffer.
I have noted that the cascades trained with the program opencv_traincascade does not run with the current version of opencv_performance. I've tried to convert the old performance cpp file to load the new types of cascades, but without success. The code is here:
#include "cv.h"
#include "highgui.h"
#include <cstdio>
#include <cmath>
#include <ctime>
#include <math.h>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#ifndef PATH_MAX
#define PATH_MAX 512
#endif /* PATH_MAX */
/*typedef struct HidCascade {
int size;
int count;
} HidCascade;
*/
typedef struct ObjectPos {
float x;
float y;
float width;
int found; /* for reference */
int neghbors;
} ObjectPos;
using namespace std;
using namespace cv;
int main(int argc, char* argv[]) {
int i, j;
char* classifierdir = NULL;
//char* samplesdir = NULL;
int saveDetected = 1;
double scale_factor = 1.1;
float maxSizeDiff = 1.5F;
float maxPosDiff = 1.1F;
/* number of stages. if <=0 all stages are used */
//int nos = -1, nos0;
int width = 25;
int height = 15;
int rocsize;
FILE* info;
FILE* resultados;
char* infoname;
char fullname[PATH_MAX];
//char detfilename[PATH_MAX];
char* filename;
//char detname[] = "det-";
CascadeClassifier cascade;
double totaltime;
if (!(resultados = fopen("resultados.txt", "w"))) {
printf("Cannot create results file.\n");
exit(-1);
}
infoname = (char*) "";
rocsize = 20;
if (argc == 1) {
printf("Usage: %s\n -data <classifier_directory_name>\n"
" -info <collection_file_name>\n"
" [-maxSizeDiff <max_size_difference = %f>]\n"
" [-maxPosDiff <max_position_difference = %f>]\n"
" [-sf <scale_factor = %f>]\n"
" [-ni]\n"
" [-rs <roc_size = %d>]\n"
" [-w <sample_width = %d>]\n"
" [-h <sample_height = %d>]\n", argv[0], maxSizeDiff,
maxPosDiff, scale_factor, rocsize, width, height);
return 0;
}
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-data")) {
classifierdir = argv[++i];
} else if (!strcmp(argv[i], "-info")) {
infoname = argv[++i];
} else if (!strcmp(argv[i], "-maxSizeDiff")) {
maxSizeDiff = (float) atof(argv[++i]);
} else if (!strcmp(argv[i], "-maxPosDiff")) {
maxPosDiff = (float) atof(argv[++i]);
} else if (!strcmp(argv[i], "-sf")) {
scale_factor = atof(argv[++i]);
} else if (!strcmp(argv[i], "-ni")) {
saveDetected = 0;
} else if (!strcmp(argv[i], "-rs")) {
rocsize = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-w")) {
width = atoi(argv[++i]);
} else if (!strcmp(argv[i], "-h")) {
height = atoi(argv[++i]);
}
}
if (!cascade.load(classifierdir)) {
printf("Unable to load classifier from %s\n", classifierdir);
return 1;
}
strcpy(fullname, infoname);
filename = strrchr(fullname, '\\');
if (filename == NULL) {
filename = strrchr(fullname, '/');
}
if (filename == NULL) {
filename = fullname;
} else {
filename++;
}
info = fopen(infoname, "r");
totaltime = 0.0;
if (info != NULL) {
int x, y, width, height;
Mat img;
int hits, missed, falseAlarms;
int totalHits, totalMissed, totalFalseAlarms;
int found;
float distance;
int refcount;
ObjectPos* ref;
int detcount;
ObjectPos* det;
int error = 0;
int* pos;
int* neg;
pos = (int*) cvAlloc(rocsize * sizeof(*pos));
neg = (int*) cvAlloc(rocsize * sizeof(*neg));
for (i = 0; i < rocsize; i++) {
pos[i] = neg[i] = 0;
}
printf("+================================+======+======+======+\n");
printf("| File Name | Hits |Missed| False|\n");
printf("+================================+======+======+======+\n");
fprintf(resultados,
"+================================+======+======+======+\n");
fprintf(resultados,
"| File Name | Hits |Missed| False|\n");
fprintf(resultados,
"+================================+======+======+======+\n");
//fprintf (resultados, "%d\n",framesCnt);
totalHits = totalMissed = totalFalseAlarms = 0;
while (!feof(info)) {
fscanf(info, "%s %d", filename, &refcount);
img = imread(fullname);
if (!img.data) {
cout << "ow" << endl;
return -1;
}
ref = (ObjectPos*) cvAlloc(refcount * sizeof(*ref));
for (i = 0; i < refcount; i++) {
error = (fscanf(info, "%d %d %d %d", &x, &y, &width, &height)
!= 4);
if (error)
break;
ref[i].x = 0.5F * width + x;
ref[i].y = 0.5F * height + y;
ref[i].width = sqrt(0.5F * (width * width + height * height));
ref[i].found = 0;
ref[i].neghbors = 0; //in the new cascade, where to get the neighbors?
}
vector<Rect> obj_detectados;
Rect retang;
if (!error) {
totaltime -= time(0);
cascade.detectMultiScale(img, obj_detectados, scale_factor, 4, 0
//|CV_HAAR_FIND_BIGGEST_OBJECT
// |CV_HAAR_DO_ROUGH_SEARCH
| CV_HAAR_SCALE_IMAGE, Size(25, 15));
totaltime += time(0);
if (obj_detectados.size() == 0) {
detcount = 0;
} else {
detcount = obj_detectados.size();
}
det = (detcount > 0) ?
((ObjectPos*) cvAlloc(detcount * sizeof(*det))) : NULL;
hits = missed = falseAlarms = 0;
for (vector<Rect>::const_iterator r = obj_detectados.begin();
r != obj_detectados.end(); r++, i++) {
Point r1, r2;
r1.x = (r->x);
r1.y = (r->y);
r2.x = (r->x + r->width);
r2.y = (r->y + r->height);
retang.x = r1.x;
retang.y = r1.y;
retang.width = abs(r2.x - r1.x);
retang.height = abs(r2.y - r1.y);
if (saveDetected) {
rectangle(img, retang, Scalar(0, 0, 255), 3, CV_AA);
}
det[i].x = 0.5F*r->width + r->x;
det[i].y = 0.5F*r->height + r->y;
det[i].width = sqrt(0.5F * (r->width * r->width
+ r->height * r->height));
det[i].neghbors = 1; // i don't know if it will work...
// det[i].neghbors = r.neighbors; --- how to do it in the new version??
found = 0;
for (j = 0; j < refcount; j++) {
distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
(det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
//cout << distance << endl;
if( (distance < ref[j].width * maxPosDiff) &&
(det[i].width > ref[j].width / maxSizeDiff) &&
(det[i].width < ref[j].width * maxSizeDiff) )
{
ref[j].found = 1;
ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
found = 1;
}
}
if (!found) {
falseAlarms++;
neg[MIN(det[i].neghbors, rocsize - 1)]++;
//neg[MIN(0, rocsize - 1)]++;
}
}
//imshow("teste", img);
if (saveDetected) {
//strcpy(detfilename, detname);
//strcat(detfilename, filename);
//strcpy(filename, detfilename);
imwrite(fullname, img);
//cvvSaveImage(fullname, img);
}
for (j = 0; j < refcount; j++) {
if (ref[j].found) {
hits++;
//pos[MIN(0, rocsize - 1)]++;
pos[MIN(ref[j].neghbors, rocsize - 1)]++;
} else {
missed++;
}
}
totalHits += hits;
totalMissed += missed;
totalFalseAlarms += falseAlarms;
printf("|%32.64s|%6d|%6d|%6d|\n", filename, hits, missed,
falseAlarms);
//printf("+--------------------------------+------+------+------+\n");
fprintf(resultados, "|%32.64s|%6d|%6d|%6d|\n", filename, hits,
missed, falseAlarms);
//fprintf(resultados,
// "+--------------------------------+------+------+------+\n");
fflush(stdout);
if (det) {
cvFree( &det);
det = NULL;
}
} /* if( !error ) */
//char c = (char) waitKey(10);
// if (c == 27)
// exit(0);
cvFree( &ref);
}
fclose(info);
printf("|%32.32s|%6d|%6d|%6d|\n", "Total", totalHits, totalMissed,
totalFalseAlarms);
fprintf(resultados, "|%32.32s|%6d|%6d|%6d|\n", "Total", totalHits,
totalMissed, totalFalseAlarms);
printf("+================================+======+======+======+\n");
fprintf(resultados,
"+================================+======+======+======+\n");
//printf("Number of stages: %d\n", nos);
//printf("Number of weak classifiers: %d\n", numclassifiers[nos - 1]);
printf("Total time: %f\n", totaltime);
fprintf(resultados, "Total time: %f\n", totaltime);
/* print ROC to stdout */
for (i = rocsize - 1; i > 0; i--) {
pos[i - 1] += pos[i];
neg[i - 1] += neg[i];
}
//fprintf(stderr, "%d\n", nos);
for (i = 0; i < rocsize; i++) {
fprintf(stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
((float) pos[i]) / (totalHits + totalMissed),
((float) neg[i]) / (totalHits + totalMissed));
}
cvFree( &pos);
cvFree( &neg);
}
return 0;
}
My doubt is about the det[i].neghbors = r.neighbors; in the old performance.cpp. How I retrieve the neighbors in this new version?
Anyone could help me to convert opencv_performance to run the new cascades from opencv_traincascade?
Many thanks!