I'm trying to get my Arduino to send data to a python script on my computer and for some reason the python script is reading the data incorrectly. Specifically, it reads the data correctly for about 4-5 receives then it starts to get out of sync. Below is my code:
Arduino:
struct sensorData
{
char beginPad[5];
int data0;
char pad0;
//int data1;
//char pad1;
//int data2;
};
union data
{
unsigned char buffer[sizeof(sensorData)];
sensorData vars;
};
data sendData;
void setup()
{
Serial.begin(9600);
static char temp[5] = {0, 1, 2, 3, 4};
memcpy(sendData.vars.beginPad, temp, 5);
sendData.vars.pad0 = 0;
//sendData.vars.pad1 = 0;
}
void loop()
{
sendData.vars.data0 = (256);
//sendData.vars.data1 = (512);
//sendData.vars.data2 = (1024);
Serial.write(sendData.buffer, sizeof(sensorData));
delay(100);
}
Python:
import serial
class SensorData:
def __init__(self, ser_obj, s_dict, p_start, p_len):
self.ser = ser_obj
self.sensor_buffer = s_dict
self.num_sensors = len(s_dict)
self.pad_start = p_start
self.pad_len = p_len
self.wait_for_beginning(p_start)
def poll(self):
for i in range(self.num_sensors):
tmp = self.ser_read()
tmp+=(self.ser_read()<<8)
print tmp
self.sensor_buffer.values()[i].append(tmp)
self.ser_read()
return self.sensor_buffer
def ser_read(self):
while True:
try:
data = ord(self.ser.read())
break
except:
continue
return data
def wait_for_beginning(self, start):
while True:
while(self.ser_read() != 0): continue
flag = 0
for i in range(1, self.pad_len):
if i == self.ser_read(): continue
else:
flag = 1
break
if flag: continue
else: break
def wait_for_end(self):
while True:
pad = self.ser_read()
if pad == self.pad_len-1:
break
#END OF CLASS
#main.py
def serial_poll( s_dict ):
dev = serial_init()
s = SensorData( dev, s_dict, 0, 5 )
while True:
sensor_buffer = s.poll()
s.wait_for_end()
print sensor_buffer
def serial_init():
ser = serial.Serial()
ser.baudrate = 9600
ser.port = '/dev/ttyACM0'
ser.open()
return ser
if __name__ == "__main__":
global sensor_buffer
sensor_buffer = { 'sensor1': [] }
serial_thread = threading.Thread( target=serial_poll, args=(sensor_buffer, ) )
serial_thread.daemon = True
serial_thread.start()
while True:
time.sleep( .1 )
I'm running the serial functions on a new thread because I have other things going on in this application. I'm basically trying to send some data that I have hard coded from the Arduino to a Linux computer. I have padding in between actual data to delimit it. At first I thought I was getting buffer overflows since each data buffer was more than 14 bytes long. I shortened it and the issue persisted. I then tried to add a delay since it might be sending data too fast. This didn't help either and now I'm out of ideas. If you need me to be more specific just let me know.
Related
I am trying to write a very simple sine wave generator that plays out through XAudio2.
Currently there is sound playing, and if I call Win32XAudioInit() and then Win32PlayTone() a tone will play, and the tone will change on subsequent calls to Win32PlayTone(), however there is a noticeable click almost every time the tone changes.
I know there are a few reasons that could cause this:
I am not keeping track of the phase-offset, which means new waves would be misaligned.
I am simply updating the Memory that the buffer is pointing to without regard to what is playing.
Regarding #2, I am not sure if XAudio wants me to create a new XAUDIO2_BUFFER and resubmit that every time I change the tone, or if I am supposed to somehow keep track of where the 'playhead' is (for lack of a better term) and only update bytes that have already been played.
I know if #2 is a problem, I won't be able to hear if I fixed it I am still plagued by problem #1.
I have read through XAudio2 - Play generated sine, when changing frequency clicking sound and I think I could figure out the sin wave problem if I knew XAudio2 was set up correctly.
Any thoughts would be helpful, thanks!
struct win32_audio_buffer
{
real32 Memory[44100 * 1]; // samples per buffer (44100) * channels 1
int BytesPerBuffer;
XAUDIO2_BUFFER XBuffer;
IXAudio2 *XEngine;
IXAudio2SourceVoice *SourceVoice;
WAVEFORMATEX WaveFormat;
};
// NOTE XAUDIO2
internal HRESULT
Win32XAudioInit(win32_audio_buffer *AudioBuffer)
{
// Initialize a COM:
HRESULT HRes;
HRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(FAILED(HRes)) { return(HRes); }
// Init XAUDIO Engine
AudioBuffer->XEngine = {};
if (FAILED(HRes = XAudio2Create(&AudioBuffer->XEngine, 0, XAUDIO2_DEFAULT_PROCESSOR)))
{ return HRes; }
// MASTER VOICE
IXAudio2MasteringVoice* XAudioMasterVoice = nullptr;
if (FAILED(HRes = AudioBuffer->XEngine->CreateMasteringVoice(&XAudioMasterVoice)))
{ return HRes; }
AudioBuffer->WaveFormat = {};
//int32 SamplesPerBuffer = 4410;
int SampleHz = 44100;
WORD Channels = 1;
WORD BitsPerChannel = 32; // 4 byte samples
int32 BufferSize = Channels * BitsPerChannel * SampleHz;
AudioBuffer->BytesPerBuffer = SampleHz * Channels;
AudioBuffer->WaveFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; // or could use WAVE_FORMAT_PCM WAVE_FORMAT_IEEE_FLOAT
AudioBuffer->WaveFormat.nChannels = Channels;
AudioBuffer->WaveFormat.nSamplesPerSec = SampleHz;
AudioBuffer->WaveFormat.wBitsPerSample = BitsPerChannel; // 32
AudioBuffer->WaveFormat.nBlockAlign = (Channels * BitsPerChannel) / 8;
AudioBuffer->WaveFormat.nAvgBytesPerSec = SampleHz * Channels * BitsPerChannel / 8;
AudioBuffer->WaveFormat.cbSize = 0; // set to zero for PCM or IEEE float
AudioBuffer->XBuffer.Flags = 0;
AudioBuffer->XBuffer.AudioBytes = SampleHz * Channels * BitsPerChannel / 8;
AudioBuffer->XBuffer.PlayBegin = 0;
AudioBuffer->XBuffer.PlayLength = 0;
AudioBuffer->XBuffer.LoopBegin = 0;
AudioBuffer->XBuffer.LoopLength = 0;
AudioBuffer->XBuffer.LoopCount = XAUDIO2_LOOP_INFINITE;
AudioBuffer->XBuffer.pContext = NULL;
AudioBuffer->XBuffer.pAudioData = (BYTE *)&AudioBuffer->Memory;
if(FAILED(HRes = AudioBuffer->XEngine->CreateSourceVoice(&AudioBuffer->SourceVoice, (WAVEFORMATEX*)&AudioBuffer->WaveFormat)))
{ return HRes; }
if(FAILED(HRes = AudioBuffer->SourceVoice->Start(0)))
{ return HRes; }
if(FAILED(HRes = AudioBuffer->SourceVoice->SubmitSourceBuffer(&AudioBuffer->XBuffer)))
{ return HRes; }
return(S_OK);
}
internal HRESULT
Win32PlayTone(win32_audio_buffer *Buffer, int32 Hz)
{
real32 PI2 = (real32)6.28318; //530718;
for(int i = 0;
i < Buffer->BytesPerBuffer;
i++)
{
real32 CurrentSample = sinf(i * PI2 / 44100 * Hz);
Buffer->Memory[i] = CurrentSample;
}
return(S_OK);
}
XAudio2 is entirely asynchronous, so you should not change the memory pointed to by a playing packet until the packet is completed or you will get clicks as you describe.
Also, when the current packet completes, you want to have another one already queued up if you want the sound to be continuous.
See these resources for learning how to program XAudio2:
https://github.com/walbourn/directx-sdk-samples/tree/master/XAudio2
https://github.com/microsoft/Xbox-ATG-Samples/tree/master/UWPSamples/Audio
DirectX Tool Kit for Audio
code:
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include <BLE2902.h>
byte flags = 0b00011110;
byte bpm;
byte rr;
byte heart[8] = { 0b00011110, 60, 60, 60, 60 , 60, 60, 60};
byte hrmPos[1] = {2};
bool _BLEClientConnected = false;
#define heartRateService BLEUUID((uint16_t)0x180D)
BLECharacteristic heartRateMeasurementCharacteristics(BLEUUID((uint16_t)0x2A37), BLECharacteristic::PROPERTY_NOTIFY);
BLECharacteristic sensorPositionCharacteristic(BLEUUID((uint16_t)0x2A38), BLECharacteristic::PROPERTY_READ);
BLEDescriptor heartRateDescriptor(BLEUUID((uint16_t)0x2901));
BLEDescriptor sensorPositionDescriptor(BLEUUID((uint16_t)0x2901));
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer) {
_BLEClientConnected = true;
};
void onDisconnect(BLEServer* pServer) {
_BLEClientConnected = false;
}
};
void InitBLE() {
BLEDevice::init("Sensor X");
// Create the BLE Server
BLEServer *pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyServerCallbacks());
// Create the BLE Service
BLEService *pHeart = pServer->createService(heartRateService);
pHeart->addCharacteristic(&heartRateMeasurementCharacteristics);
heartRateMeasurementCharacteristics.addDescriptor(&heartRateDescriptor);
heartRateMeasurementCharacteristics.addDescriptor(new BLE2902());
pHeart->addCharacteristic(&sensorPositionCharacteristic);
sensorPositionCharacteristic.addDescriptor(&sensorPositionDescriptor);
pServer->getAdvertising()->addServiceUUID(heartRateService);
pHeart->start();
// Start advertising
pServer->getAdvertising()->start();
}
void setup() {
Serial.begin(115200);
Serial.println("Start");
InitBLE();
bpm = 1;
rr = 800;
}
void loop() {
// put your main code here, to run repeatedly:
heart[1] = (byte)bpm;
int energyUsed = 3000;
heart[3] = energyUsed / 256;
heart[6] = (byte)bpm;
heart[2] = energyUsed - (heart[2] * 256);
Serial.println(bpm);
Serial.println(rr);
heartRateMeasurementCharacteristics.setValue(heart, 8);
heartRateMeasurementCharacteristics.notify();
sensorPositionCharacteristic.setValue(hrmPos, 1);
rr++;
bpm++;
delay(2000);
}
I have the above code - and I have been looking at this here but I can't figure out how do I pass the RR data over BLE. I set the flags according to the BLE spec shown here. But whenever I use an app to see the data "HRV Logger", it says that I am not transmitted RR data. I thought all I had to do was pass heart[6] data and that would show up as RR. I have dummy information being passed since I'm not connected to any sensors. Help would be helpful, determining how to pass the RR data across, thanks! (for future reference I am using the Sparkfun ESP32, but this shouldn't affect solving the issue since it has to do with protocols)
It's possible to print wpa passphrase in hostapd (by editing the code)?
This is the conf of hostapd (we use TKIP) :
wpa=1
#wpa_psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
wpa_passphrase=passphrase
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
In the file hostpad/src/ap/wpa_auth.c, we have lots of information about the connection :
SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
{
struct wpa_ptk PTK;
int ok = 0, psk_found = 0;
const u8 *pmk = NULL;
unsigned int pmk_len;
SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk);
sm->EAPOLKeyReceived = FALSE;
sm->update_snonce = FALSE;
/* WPA with IEEE 802.1X: use the derived PMK from EAP
* WPA-PSK: iterate through possible PSKs and select the one matching
* the packet */
for (;;) {
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
pmk = wpa_auth_get_psk(sm->wpa_auth, sm->addr,
sm->p2p_dev_addr, pmk);
if (pmk == NULL)
break;
psk_found = 1;
pmk_len = PMK_LEN;
} else {
pmk = sm->PMK;
pmk_len = sm->pmk_len;
}
wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK);
if (wpa_verify_key_mic(sm->wpa_key_mgmt, &PTK,
sm->last_rx_eapol_key,
sm->last_rx_eapol_key_len) == 0) {
ok = 1;
break;
}
if (!wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt))
break;
}
if (!ok) {
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
"invalid MIC in msg 2/4 of 4-Way Handshake");
if (psk_found)
wpa_auth_psk_failure_report(sm->wpa_auth, sm->addr);
return;
}
#ifdef CONFIG_IEEE80211R
// ....
#endif /* CONFIG_IEEE80211R */
sm->pending_1_of_4_timeout = 0;
eloop_cancel_timeout(wpa_send_eapol_timeout, sm->wpa_auth, sm);
if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt)) {
/* PSK may have changed from the previous choice, so update
* state machine data based on whatever PSK was selected here.
*/
os_memcpy(sm->PMK, pmk, PMK_LEN);
sm->pmk_len = PMK_LEN;
}
sm->MICVerified = TRUE;
os_memcpy(&sm->PTK, &PTK, sizeof(PTK));
sm->PTK_valid = TRUE;
}
My knowledge in networks are limited, and I do not understand very well WPA protocol. There is an article interesting on the question here, but the situation is a little bit different because we are in the case of an attack "man in the middle".
I'm building an app that, in part, needs to resample any input PCM audio file that isn't 44100Hz to 44.1 (or at least make a best effort to do so).
To handle the resampling I'm using soxr. soxr has no dependencies and is lightweight, which is ideal in this case, but it offers no native file I/O. I have very limited experience with IO streams in C, so I'm hitting a wall. The app is being designed modularly, so I need the resample process to create an output file that can then be passed on to other processors, rather than simply dealing with the output stream directly.
In order to create that output file, I'm trying to take the data generated by the soxr resampling process, and pass it to libsndfile, which should be able to write the audio out to a file.
Below is an extremely verbose explanation of where I'm at, though I'm at a loss for why it's crashing. I suspect it has something to do with how buffers are being allocated and used. (Note: The input file is being read with sndfile prior to this code)
(Here's a single gist of the entire thing)
Basic resampler options
// Use "high quality" resampling
unsigned int q_recipe = SOXR_HQ;
// No
unsigned long q_flags = 0;
// Create the q_spec
soxr_quality_spec_t q_spec = soxr_quality_spec(q_recipe, q_flags);
Map the sndfile format to a soxr format
soxr_datatype_t itype;
// Get the SFINFO format
int iformat = self.inputFileInfo.format;
// Set the soxr itype to the corresponding format
if ((iformat & SF_FORMAT_FLOAT) == SF_FORMAT_FLOAT) {
itype = SOXR_FLOAT32_S;
} else if ((iformat & SF_FORMAT_DOUBLE) == SF_FORMAT_DOUBLE) {
itype = SOXR_FLOAT64_S;
} else if ((iformat & SF_FORMAT_PCM_32) == SF_FORMAT_PCM_32) {
itype = SOXR_INT32_S;
} else {
itype = SOXR_INT16_S;
}
Setup soxr IO spec
// Always want the output to match the input
soxr_datatype_t otype = itype;
soxr_io_spec_t io_spec = soxr_io_spec(itype, otype);
Threading
// A single thread is fine
soxr_runtime_spec_t runtime_spec = soxr_runtime_spec(1);
Construct the resampler
soxr_error_t error;
// Input rate can be read from the SFINFO
double const irate = self.inputFileInfo.samplerate;
// Output rate is defined elsewhere, but this generally = 44100
double const orate = self.task.resampler.immutableConfiguration.targetSampleRate;
// Channel count also comes from SFINFO
unsigned chans = self.inputFileInfo.channels;
// Put it all together
soxr_t soxr = soxr_create(irate, orate, chans, &error, &io_spec, &q_spec, &runtime_spec);
Read, resample & write
I'm not really confident in any of the following code, but I've triple checked the math and everything seems to meet the expectations of the libraries' APIs.
// Frames in sndfile are called Samples in soxr
// One frame is 1 item per channel
// ie frame_items = 1 item * channels
size_t const iframeitems = (1 * chans);
// item size is the data type size of the input type
//
size_t iitemsize;
if ((iformat & SF_FORMAT_FLOAT) == SF_FORMAT_FLOAT) {
iitemsize = sizeof(Float32);
} else if ((iformat & SF_FORMAT_DOUBLE) == SF_FORMAT_DOUBLE) {
iitemsize = sizeof(Float64);
} else if ((iformat & SF_FORMAT_PCM_32) == SF_FORMAT_PCM_32) {
iitemsize = sizeof(int32_t);
} else {
iitemsize = sizeof(int16_t);
}
// frame size is item size * items per frame (channels)
// eg for 2 channel 16 bit, frame size = 2 * 2
size_t const iframesize = (iframeitems * iitemsize);
// Number of frames to read (arbitrary)
sf_count_t const ireqframes = 1024;
// Size of the buffer is number of frames * size per frame
size_t const ibufsize = iframesize * ireqframes;
void *ibuf = malloc(ibufsize);
// Output
//////////////////////////////
// These match the input
size_t const oframeitems = iframeitems;
size_t const oitemsize = iitemsize;
// frame size is item size * items per frame (channels)
size_t const oframesize = (oframeitems * oitemsize);
// Number of frames expected after resampling
// eg
// orate = 44100
// irate = 48000
// ireqframe = 1024
// expect fewer frames (downsample)
// (44100 / 4800) * 1024 = 940.8
// Add 0.5 to deal with rounding?
sf_count_t const oexpframes = (ireqframes * (orate / irate)) + 0.5;
// Size of the buffer is number of frames * size per frame
size_t const obufsize = oframesize * oexpframes;
void *obuf = malloc(obufsize);
// Go
//////////////////////////////
size_t total_resample_output_frame_count = 0;
size_t need_input = 1;
sf_count_t num_frames_written = 0;
do {
sf_count_t num_frames_read = 0;
size_t actual_resample_output_samples = 0;
// Read the input file based on its type
// num_frames_read should be 1024
if (otype == SOXR_INT16_S || otype == SOXR_INT32_S) {
num_frames_read = sf_readf_int(self.inputFile, ibuf, ireqframes);
} else if (otype == SOXR_FLOAT32_S) {
num_frames_read = sf_readf_float(self.inputFile, ibuf, ireqframes);
} else {
num_frames_read = sf_readf_double(self.inputFile, ibuf, ireqframes);
}
// If there were no frames left to read we're done
if (num_frames_read == 0) {
// passing NULL input buffer to soxr_process indicates End-of-input
ibuf = NULL;
need_input = 0;
}
// Run the resampling on frames read from the input file
error = soxr_process(soxr, ibuf, num_frames_read, NULL, obuf, oexpframes, &actual_resample_output_samples);
total_resample_output_frame_count += actual_resample_output_samples;
// Write the resulting data to output file
// num_frames_written should = actual_resample_output_samples
if (otype == SOXR_INT16_S || otype == SOXR_INT32_S) {
num_frames_written = sf_writef_int(self.outputFile, obuf, actual_resample_output_samples);
} else if (otype == SOXR_FLOAT32_S) {
num_frames_written = sf_writef_float(self.outputFile, obuf, actual_resample_output_samples);
} else {
num_frames_written = sf_writef_double(self.outputFile, obuf, actual_resample_output_samples);
}
} while (!error && need_input);
soxr_delete(soxr);
free(obuf), free(ibuf);
This gives and EXC_BAD_ACCESS on soxr_process. I have no idea what else to try at this point.
The _S in data types like SOXR_INT32_S mean that you're using split channels, and from the example 4-split-channels.c it seems that in that case you need to pass an array of pointers, one for each channel.
However, in the code above you just pass a single allocated block of memory so I'm guessing you're expecting interleaved channel data. Perhaps you can try changing the _S to _I.
im writing a file transfer application to send and receive a large data like 1 GB.. but i think when i read the data from the file and fill it into a byte array it stored on RAM and that would effect on the computer speed .. should i do like :
(loop till end of the file)
{
read 128 MB from the file into byte array
(loop till end of 128)
{
send 1 kb to server
}
byte array = null
}
if that is right ..
which is better to do !! beginSend and beginReceive to send the large file or just loop to send the file
i would be glad if you teach me with some code
thanks in advance :)
Windows will start behaving oddly, if you [begin]Send more than ca. 1MB in one go. This differs between Windows versions, network drivers, shoe size of user and moon phase. Below 1 MB you should be fine.
So, either
(loop till end of the file)
{
read 128 MB from the file into byte array
(loop till end of 128)
{
send 1 MB to server
}
byte array = null
}
or, if it is really a file
SendFile(filename[,...])
even 128mb is not a good way .. its better to read a small buffer .. then send it straight to the other side
check it out.
after you send the fileName and the fileSize to other side
this should be common in (server/client)
FileStream fs;
NetworkStream network;
int packetSize = 1024*8;
Send method
public void Send(string srcPath, string destPath)
{
byte data;
string dest = Path.Combine(destPath, Path.GetFileName(srcPath));
using (fs = new FileStream(srcPath, FileMode.Open, FileAccess.Read))
{
try
{
long fileSize = fs.Length;
long sum = 0;
int count = 0;
data = new byte[packetSize];
while (sum < fileSize)
{
count = fs.Read(data, 0, packetSize);
network.Write(data, 0, count);
sum += count;
}
network.Flush();
}
finally
{
fs.Dispose();
data = null;
}
}
}
Receive method:
public void Receive(string destPath, long fileSize)
{
byte data;
using (fs = new FileStream(destPath, FileMode.Create, FileAccess.Write))
{
try
{
int count = 0;
long sum = 0;
data = new byte[packetSize];
while (sum < fileSize)
{
count = network.Read(data, 0, packetSize);
fs.Write(data, 0, count);
sum += count;
}
}
finally
{
fs.Dispose();
data = null;
}
}
}