Thanks for read my topic
I tried to record the sound, I managed to record the sound at a sample rate of 8 kHz.
this is my code it works great. But I need more sample rate like 11kHz or 16 kHz, I do not know how I can increase my sample rate to this rate.i use STM32F103C8
I got this code in the source https://www.hackster.io/christopher-william-sutjiono/read-audio-amplifier-circuit-output-using-stm-32-d9acb5
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_TIM3_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE END 0 */
#define SAMP 8000
int main(void)
{
int k;
uint8_t buf[40];
uint16_t dat[SAMP]; // store ADC value 'SAMP'variable is 8000 1 sec for store audio
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_TIM3_Init();
MX_USART1_UART_Init();
HAL_TIM_Base_Start(&htim3);
while (1)
{
for(k=0;k<SAMP;k++)
{
while((__HAL_TIM_GET_COUNTER(&htim3))<124);
HAL_ADC_Start(&hadc1);
HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
dat[k] = HAL_ADC_GetValue(&hadc1); //GET ADC Value
}
// for loop to print sammples to computer screen with 1 msec pause between samples
for (k=0;k<SAMP;k++)
{
sprintf((char*)buf,"%d\r\n", dat[k]);
HAL_UART_Transmit(&huart1, buf, strlen((char*)buf), HAL_MAX_DELAY);
HAL_Delay(1);
}
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,GPIO_PIN_SET);
HAL_Delay(3000);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13,GPIO_PIN_RESET);
HAL_Delay(3000);
}
}
htim3.Instance = TIM3;
htim3.Init.Prescaler = 16-1;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 125-1;
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
[1]: https://www.hackster.io/christopher-william-sutjiono/read-audio-amplifier-circuit-output-using-stm-32-d9acb5
It looks like the line while((__HAL_TIM_GET_COUNTER(&htim3))<124); is defining your sample rate, reducing the magic number from 124 will increase your sample rate.
There's almost certainly a better way to do this, such as a timer triggered DMA or similar.
EDIT 2: I got the solution. Anytime someone wants the code I'd be happy to provide. Peace.
Topic:
I'm trying an experiment of echoing strings that I receive in my arduino.
So this is the code so far:
byte byteRead = 0;
bool readable = LOW;
char fullString[50];
int index = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
// State 1
if (Serial.available()) {
readable = HIGH; // flag to enter in the next state when there's nothing else to read
byteRead = Serial.read();
fullString[index] = (char)byteRead;
index++;
}
// State 2
if (readable == HIGH && !Serial.available()){
fullString[index] = '\0'; // '\0' to terminate the string
Serial.println(fullString);
// resets variables
index = 0;
readable = LOW;
}
/**
* Somehow a delay prevents characters of the string from having
* a line printed between them.
* Anyways, when the string is too long, a line is printed between
* the first and second characters
*/
delay(5);
}
Somehow this delay in the end prevents the characters of the string from having a line printed between them, like this:
H
e
l
l
o
Nonetheless, when the string is too long, a line is printed between the first and second characters.
Do you know a better way of doing this?
EDIT: Next time I'd appreciate answers from someone who actually KNOWS programming. Not just condescending idiots.
that's my String Echo
#define MAX_BUFFER_SIZE 0xFF
char buffer[MAX_BUFFER_SIZE];
void setup() {
Serial.begin(115200);
buffer[0] = '\0';
}
void loop() {
while (Serial.available() > 0) {
char incomingByte;
size_t i = 0;
do {
incomingByte = Serial.read();
buffer[i++] = incomingByte;
} while (incomingByte != '\0' && i < MAX_BUFFER_SIZE);
if(i > 0){
delay(1000); /// delay for the echo
Serial.write(buffer, i);
}
}
}
You want to echo the string read, so just echo the input.
void setup() {
Serial.begin(9600);
}
void loop() {
int c = Serial.read();
if (c >= 0) Serial.write(c);
}
http://postimg.org/image/btd4u4esx/
Hi,
This is the output image(black keyboard with white background) of a code that i modified from one of android samples. I want to take byte data from java file and send it to cpp using jni as unsigned character and and i am trying to display the video frames i receive using open cv mat.
JAVA CODE:
native int Fibonacci( byte[] n,int width, int height );
static {
System.loadLibrary( "CopyofHDRViewFinder" );
}
#Override
public void run() {
// y = 0.299*r + 0.587*g + 0.114*b
Log.v(TAG, "enter in imageSaver! Format is: " + mImage.getFormat());
ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
int heigth=mImage.getHeight();
int width=mImage.getWidth();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
int a=Fibonacci(bytes,width,heigth);
int pixelsize=mImage.getWidth()*mImage.getHeight();
System.out.println("framewidth:"+mImage.getWidth());
System.out.println("frameheight:"+mImage.getHeight());
System.out.println("totalnumberofpixels:"+pixelsize);
System.out.println("lastpixelvalue:"+a);
then the CPP code:(jni)
JNIEXPORT jint JNICALL Java_com_example_android_hdrviewfinder_HdrViewfinderActivity3_00024ImageSaver_Fibonacci
(JNIEnv *env, jobject obj, jbyteArray array, jint width, jint height)
{
i=i+1;
int len = env->GetArrayLength (array);
unsigned char* img = new unsigned char[len];
env->GetByteArrayRegion (array, 0, len-1, reinterpret_cast<jbyte*>(img));
const cv::Mat hdrimg(height,width, CV_8UC1, img);
char buffer[50];
int ab=sprintf(buffer,"/storage/emulated/0/Android/IMAGE%d.jpg",i);
cv::imwrite(buffer, hdrimg);
/*cv::namedWindow("HDRImage");
cv::imshow("HDRImage", hdrimg);
cv::waitKey(0);*/
printf("\n %d", width);
printf("\n %d", height);
int a;
for(int i=0;i<width*height;i++)
{
a=(int)img[i];
}
int c=width*height;
return a;
}
This returns proper pixel values from 0 to 255. my issue is not that. when i check the image it looks blurry and totally horrible, but still i cant deduce that its a keyboard slightly. Anyone has seen similar results? Help, if you can..
I'm using Processing and an Arduino Uno to control the position of a circle on the screen using two potentiometers. The Arduino and computer communicate via bluetooth. Here is the code for the Processing sketch:
import processing.serial.*;
Serial myPort;
int x, y;
void setup() {
size(400, 400);
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 115200);
myPort.bufferUntil('\n');
background(255);
noStroke();
}
void draw() {
}
void serialEvent(Serial myPort) {
println("here");
String inString = myPort.readStringUntil('\n');
if (inString != null) {
inString = trim(inString);
String items[] = split(inString, ',');
if (items.length > 1) {
float a = float(items[0]);
float b= float(items[1]);
x = (int) map(a, 0, 1023, 0, width);
y = (int) map(b, 0, 1023, 0, height);
background(255);
fill(255, 0, 0);
ellipse(x, y, 10, 10);
}
}
//myPort.write('\r');
}
Here is the code for the Arduino:
const int left_pot = A2;
const int right_pot = A3;
int x;
int y;
void setup(){
Serial.begin(115200);
/* while (Serial.available()<=0){
Serial.println("hello?");
}*/
}
void loop(){
//if (Serial.available() > 0) {
int inByte = Serial.read();
x = analogRead(left_pot);
y = analogRead(right_pot);
Serial.print(x);
Serial.print(", ");
Serial.println(y);
delay(2);
//}
}
As posted, the code works but the dot on the screen is very jittery. So I tried to implement a hand-shaking protocol based on "How Things Talk" (Igoe, page 62). The commented out lines are supposed to do that. But when they are uncommented, the red dot no longer displays and the processing sketch never gets to the command println("here").
I'm using 32-bit Processing 2.0.1.
Your Arduino sketch waits until it receives some data before it sends data. So your Processing sketch must first send something through serial to the Arduino. Currently it does not. Try adding something to get it to print:
void setup() {
size(400, 400);
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 115200);
myPort.bufferUntil('\n');
background(255);
noStroke();
myPort.write('\r'); //Get the arduino to reply
}
Im using GDI+ in C++ to draw a chart control. I want to know if there is any performance difference between the above 2 functions. I am not lazy to write code for DrawLines() but it is that doing so makes my code complex. So im weighin the chances of whether to make code execution faster at the expense of reducing readability and potentially increasing errors and bugs.
Any help wud be appreciated.
Eraj.
There shouldn't be a significant difference between the two for most drawing activities, but to be sure, I wrote up a test project to compare the difference between them (well, actually 3 of them).
For a very large number of lines (x25000) on my machine, DrawLines() (640ms) was about 50% faster over DrawLine() (420ms). To be honest here, I also misread the question the first time around and wrote my initial test in C#. Performance was about the same between the two, which is to be expected as .NET Graphics are based upon GDI+.
Just out of curiosity, I tried regular GDI, which I expect would be faster. Using the win32 PolyLine() (530ms) function was about 20% faster, with 45000 lines. This is 116% faster than using GDI+ DrawLines(). Even more stunning, perhaps, is that using win32 LineTo() instead of GDI+ DrawLine() results in times under 125ms. With an assumed time of 125ms and 45000 lines, this method is at least 800% faster. (Timer resolution and thread timing make it difficult to measure performance in this threshold without resorting to QueryPerformanceCounter and other timing methods of higher frequency.)
However, I should caution against making the assumption that this is a significant bottleneck in drawing code. Many of the performance improvements that can be made will have nothing to do with what objects have to be drawn. I would guess that your requirements will probably dictate that a few hundred items may need to be drawn in normal operation for your control. In that case, I would recommend you write your drawing code to be as straightforward and bug-free as you can, as debugging drawing issues can be an expensive use of time and potentially less beneficial as improving the rest of your control or your application.
Also, if you need to actively update thousands of items, you will see much higher performance gains by moving to a back-buffered solution. This should also make it easier to develop code to draw your control, aside from managing the off-screen buffer.
Here are my source code examples. Each of them handles mouse clicks to alternate between using bulk drawing versus itemized drawing.
GDI+, hosted in a barebones MFC SDI App
This assumes that someone has already declared GDI+ headers and written code to initialize/teardown GDI+.
In ChildView.h
// Attributes
public:
bool m_bCompositeMode;
// Operations
public:
void RedrawScene(Graphics &g, int lineCount, int width, int height);
PointF *CreatePoints(int lineCount, int width, int height);
void ReportTime(Graphics &g, int lineCount, DWORD tickSpan);
public:
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
In ChildView.cpp, added to PreCreateWindow()
m_bCompositeMode = false;
Remainder of ChildView.cpp, including OnPaint() and Message Map changes.
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
RECT rcClient;
::GetClientRect(this->GetSafeHwnd(), &rcClient);
Graphics g(dc.GetSafeHdc());
g.Clear(Color(0, 0, 0));
RedrawScene(g, 25000, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
}
void CChildView::RedrawScene(Graphics &g, int lineCount, int width, int height)
{
DWORD tickStart = 0;
DWORD tickEnd = 0;
Pen p(Color(0, 0, 0x7F));
PointF *pts = CreatePoints(lineCount, width, height);
tickStart = GetTickCount();
if (m_bCompositeMode)
{
g.DrawLines(&p, pts, lineCount);
}
else
{
int i = 0;
int imax = lineCount - 1;
for (i = 0; i < imax; i++)
{
g.DrawLine(&p, pts[i], pts[i + 1]);
}
}
tickEnd = GetTickCount();
delete[] pts;
ReportTime(g, lineCount, tickEnd - tickStart);
}
void CChildView::ReportTime(Graphics &g, int lineCount, DWORD tickSpan)
{
CString strDisp;
if(m_bCompositeMode)
{
strDisp.Format(_T("Graphics::DrawLines(Pen *, PointF *, INT) x%d took %dms"), lineCount, tickSpan);
}
else
{
strDisp.Format(_T("Graphics::DrawLine(Pen *, PointF, PointF) x%d took %dms"), lineCount, tickSpan);
}
// Note: sloppy, but simple.
Font font(L"Arial", 14.0f);
PointF ptOrigin(0.0f, 0.0f);
SolidBrush br(Color(255, 255, 255));
Status s = g.DrawString(strDisp, -1, &font, ptOrigin, &br);
}
PointF* CChildView::CreatePoints(int lineCount, int width, int height)
{
if(lineCount <= 0)
{
PointF *ptEmpty = new PointF[2];
ptEmpty[0].X = 0;
ptEmpty[0].Y = 0;
ptEmpty[1].X = 0;
ptEmpty[1].Y = 0;
return ptEmpty;
}
PointF *pts = new PointF[lineCount + 1];
int i = 1;
while(i < lineCount)
{
pts[i].X = (float)(rand() % width);
pts[i].Y = (float)(rand() % height);
i++;
}
return pts;
}
void CChildView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bCompositeMode = !m_bCompositeMode;
this->Invalidate();
CWnd::OnLButtonUp(nFlags, point);
}
C#.NET, hosted in a basebones WinForms App, with default class Form1
Set a default size for the form, equal to the size of the MFC version if you are comparing the two. A size-change handler could be added as well.
public Form1()
{
InitializeComponent();
bCompositeMode = false;
}
bool bCompositeMode;
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(Color.Black);
RedrawScene(e.Graphics, 25000, this.ClientRectangle.Width, this.ClientRectangle.Height);
}
private void RedrawScene(Graphics g, int lineCount, int width, int height)
{
DateTime dtStart = DateTime.MinValue;
DateTime dtEnd = DateTime.MinValue;
using (Pen p = new Pen(Color.Navy))
{
Point[] pts = CreatePoints(lineCount, width, height);
dtStart = DateTime.Now;
if (bCompositeMode)
{
g.DrawLines(p, pts);
}
else
{
int i = 0;
int imax = pts.Length - 1;
for (i = 0; i < imax; i++)
{
g.DrawLine(p, pts[i], pts[i + 1]);
}
}
dtEnd = DateTime.Now;
}
ReportTime(g, lineCount, dtEnd - dtStart);
}
private void ReportTime(Graphics g, int lineCount, TimeSpan ts)
{
string strDisp = null;
if (bCompositeMode)
{
strDisp = string.Format("DrawLines(Pen, Point[]) x{0} took {1}ms", lineCount, ts.Milliseconds);
}
else
{
strDisp = string.Format("DrawLine(Pen, Point, Point) x{0} took {1}ms", lineCount, ts.Milliseconds);
}
// Note: sloppy, but simple.
using (Font font = new Font(FontFamily.GenericSansSerif, 14.0f, FontStyle.Regular))
{
g.DrawString(strDisp, font, Brushes.White, 0.0f, 0.0f);
}
}
private Point[] CreatePoints(int count, int width, int height)
{
Random rnd = new Random();
if (count <= 0) { return new Point[] { new Point(0,0), new Point(0,0)}; }
Point[] pts = new Point[count + 1];
pts[0] = new Point(0, 0);
int i = 1;
while (i <= count)
{
pts[i] = new Point(rnd.Next(width), rnd.Next(height));
i++;
}
return pts;
}
private void Form1_Click(object sender, EventArgs e)
{
bCompositeMode = !bCompositeMode;
Invalidate();
}
Regular GDI, hosted in a barebones MFC SDI App
In ChildView.h
// Attributes
public:
bool m_bCompositeMode;
// Operations
public:
void RedrawScene(HDC hdc, int lineCount, int width, int height);
POINT *CreatePoints(int lineCount, int width, int height);
void ReportTime(HDC hdc, int lineCount, DWORD tickSpan);
public:
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
In ChildView.cpp
Update PreCreateWindow() just as in the GDI+ sample.
BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
ON_WM_LBUTTONUP()
END_MESSAGE_MAP()
void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
HDC hdc = dc.GetSafeHdc();
HBRUSH brClear = (HBRUSH)::GetStockObject(BLACK_BRUSH);
RECT rcClient;
::GetClientRect(this->m_hWnd, &rcClient);
::FillRect(hdc, &rcClient, brClear);
::DeleteObject(brClear);
RedrawScene(hdc, 45000, rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
}
void CChildView::RedrawScene(HDC hdc, int lineCount, int width, int height)
{
DWORD tickStart = 0;
DWORD tickEnd = 0;
HPEN p = ::CreatePen(PS_SOLID, 1, RGB(0, 0, 0x7F));
POINT *pts = CreatePoints(lineCount, width, height);
HGDIOBJ prevPen = SelectObject(hdc, p);
tickStart = GetTickCount();
if(m_bCompositeMode)
{
::Polyline(hdc, pts, lineCount);
}
else
{
::MoveToEx(hdc, pts[0].x, pts[0].y, &(pts[0]));
int i = 0;
int imax = lineCount;
for(i = 1; i < imax; i++)
{
::LineTo(hdc, pts[i].x, pts[i].y);
}
}
tickEnd = GetTickCount();
::SelectObject(hdc, prevPen);
delete pts;
::DeleteObject(p);
ReportTime(hdc, lineCount, tickEnd - tickStart);
}
POINT *CChildView::CreatePoints(int lineCount, int width, int height)
{
if(lineCount <= 0)
{
POINT *ptEmpty = new POINT[2];
memset(&ptEmpty, 0, sizeof(POINT) * 2);
return ptEmpty;
}
POINT *pts = new POINT[lineCount + 1];
int i = 1;
while(i < lineCount)
{
pts[i].x = rand() % width;
pts[i].y = rand() % height;
i++;
}
return pts;
}
void CChildView::ReportTime(HDC hdc, int lineCount, DWORD tickSpan)
{
CString strDisp;
if(m_bCompositeMode)
{
strDisp.Format(_T("PolyLine(HDC, POINT *, int) x%d took %dms"), lineCount, tickSpan);
}
else
{
strDisp.Format(_T("LineTo(HDC, HPEN, int, int) x%d took %dms"), lineCount, tickSpan);
}
HFONT font = (HFONT)::GetStockObject(SYSTEM_FONT);
HFONT fontPrev = (HFONT)::SelectObject(hdc, font);
RECT rcClient;
::GetClientRect(this->m_hWnd, &rcClient);
::ExtTextOut(hdc, 0, 0, ETO_CLIPPED, &rcClient, strDisp.GetString(), strDisp.GetLength(), NULL);
::SelectObject(hdc, fontPrev);
::DeleteObject(font);
}
void CChildView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_bCompositeMode = !m_bCompositeMode;
this->Invalidate();
CWnd::OnLButtonUp(nFlags, point);
}