Writing to EEPROM could not be completed as it resets the board - c

I am writing this program to write byte of data to each memeory location and then read and compare the stored bytes. However, when i am writing the data through FOR loop, the loop ends after 749 Writes and reset the Micro. i am resetting the WDT so that shouldnt be an issue. its a fairly simple programme and I was expecting it to work smoothly. here is the code:
I am using PIC24FJ256GB210 with 24LC512K serial EEPROM.
void memorytest2 (void)
{
unsigned int number;
unsigned int data =100;
ResetCOP();
if (loop == 1)
{
for (number=500; number < 1500; number++)
{
ResetCOP();
WriteEEByte(0xAA, EEPROMStart+data);
}
ResetCOP();
data++;
}
loop =0;
data =0;
number =500;
}
void WriteEEByte (unsigned char source,unsigned int dest)
{
I2C2CONbits.RCEN = 0; // disable rx MODE AS MASTER
StartWrite(dest); // start write process at address y
I2C2TRN = source; // put data in buffer
while (I2C2STATbits.TRSTAT);// wait for transmit to complete - including ack
I2C2CONbits.PEN = 1; // send stop condition to terminate write
while (I2C2CONbits.PEN);
ReadBusy(); //write delay (~5mS)
}
void ResetCOP (void)
{
asm("clrwdt");
}

Related

Array Data Reading Failed

I am reading the data from a "Torque Wrench" using "USB Host Shield2.0" and Arduino UNO. I am receiving correct data from my "Torque Wrench" Data is receiving in a array.
But when I started reading data after "for" loop inside Void loop() I am receiving incorrect data. I attached Both output pictures correct and incorrect data.
Basically I am read data from Torque Wrench and send to receiver using Nrf24l01. I am receiving incorrect data.
My question is :- Why I am reading Incorrect data outside "for" loop.
Correct Data inside "for" loop :- enter image description here
Incorrect Data outside "for" loop :- enter image description here
#include <SPI.h> // for SPI communication
#include <nRF24L01.h>
#include <RF24.h>
#include <cdcacm.h>
#include <usbhub.h>
//#include "pgmstrings.h"
// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>
RF24 radio(7, 8); // CE, CSN
const byte address[6] = {'R','x','A','A','A','B'}; // the address the the module
class ACMAsyncOper : public CDCAsyncOper
{
public:
uint8_t OnInit(ACM *pacm);
};
uint8_t ACMAsyncOper::OnInit(ACM *pacm)
{
uint8_t rcode;
// Set DTR = 1 RTS=1
rcode = pacm->SetControlLineState(3);
if (rcode)
{
ErrorMessage<uint8_t>(PSTR("SetControlLineState"), rcode);
return rcode;
}
LINE_CODING lc;
lc.dwDTERate = 9600;
lc.bCharFormat = 0;
lc.bParityType = 0;
lc.bDataBits = 8;
rcode = pacm->SetLineCoding(&lc);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SetLineCoding"), rcode);
return rcode;
}
USB Usb;
//USBHub Hub(&Usb);
ACMAsyncOper AsyncOper;
ACM Acm(&Usb, &AsyncOper);
void setup() {
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MAX);
radio.stopListening();
#if !defined(__MIPSEL__)
while (!Serial);
#endif
Serial.println("Start");
if (Usb.Init() == -1)
Serial.println("USB Not Connected");
delay( 200 );
}
void loop() {
Usb.Task();
if( Acm.isReady()) {
uint8_t rcode;
/* reading the keyboard */
if(Serial.available()) {
uint8_t data= Serial.read();
/* sending to the phone */
rcode = Acm.SndData(1, &data);
if (rcode)
ErrorMessage<uint8_t>(PSTR("SndData"), rcode);
}
delay(10);
uint8_t buf[64];
uint16_t rcvd = 64;
char text[64];
rcode = Acm.RcvData(&rcvd, buf);
if (rcode && rcode != hrNAK)
ErrorMessage<uint8_t>(PSTR("Ret"), rcode);
if ( rcvd ) {
for(uint16_t i=0; i < rcvd; i++ )
{
// Serial.print((char)buf[i]); // correct Data read from torque wrench
text[i] = (char)buf[i];
}
Serial.println(text); // reading wrong data here
//radio.write(&text, sizeof(text));
//Serial.println(text);
}
delay(10);
}
}
Character arrays must be null-terminated to count as C strings.
After the for loop, add text[rcvd] = '\0';
Also, your rcvd is fixed at 64. It needs to be one less than the array size for the null terminator to fit.

Receiving AT commands

I'm using a microcontroller to communicate with a SIM808 module and I want to send and receive AT commands.
The problem right now is that for some commands I receive only some portions of the answers I should receive, but for some others I receive what I should. For example, if I shut down the module I receive "NORMAL POWER DOWN", as expected.
I believe I'm receiving everything, I'm just not being capable of seeing it. I receive the beginning and the end of the response, so the problem should be on the way I parse and buffer. I'm using a FIFO buffered RXC interrupt.
For example, for the command "AT+CBC" I should receive something like:
"
+CBC: 1,96,4175
OK
"
But I receive "+CBC1,4130OK"
(I replaced the unreadable characters with a dot)
bool USART_RXBufferData_Available(USART_data_t * usart_data)
{
/* Make copies to make sure that volatile access is specified. */
uint8_t tempHead = usart_data->buffer.RX_Head;
uint8_t tempTail = usart_data->buffer.RX_Tail;
/* There are data left in the buffer unless Head and Tail are equal. */
return (tempHead != tempTail);
}
uint8_t USART_receive_array (USART_data_t * usart_data, uint8_t * arraybuffer)
{
uint8_t i = 0;
while (USART_RXBufferData_Available(usart_data))
{
arraybuffer[i] = USART_RXBuffer_GetByte(usart_data);
++i;
}
return i;
}
void USART_send_array (USART_data_t * usart_data, uint8_t * arraybuffer, uint8_t buffersize)
{
uint8_t i = 0;
/* Wait until it is possible to put data into TX data register.
* NOTE: If TXDataRegister never becomes empty this will be a DEADLOCK. */
while (i < buffersize)
{
bool byteToBuffer;
byteToBuffer = USART_TXBuffer_PutByte(usart_data, arraybuffer[i]);
if(byteToBuffer)
{
++i;
}
}
}
void send_AT(char * command){
uint8_t TXbuff_size = strlen((const char*)command);
USART_send_array(&expa_USART_data, (uint8_t *)command, TXbuff_size);
fprintf(PRINT_DEBUG, "Sent: %s\n\n", command);
}
void receive_AT(uint8_t *RXbuff){
memset (RXbuff, 0, 100);
uint8_t bytes = 0;
bytes = USART_receive_array(&expa_USART_data, RXbuff);
int n;
if (bytes>0)
{
RXbuff[bytes]=0;
for (n=0;n<bytes;n++)
{
if (RXbuff[n]<32)
{
RXbuff[n]='.';
}
}
}
fprintf(PRINT_DEBUG, "Received: %s\n\n", RXbuff);
}
int main(){
unsigned char RXbuff[2000];
send_AT("ATE0\r\n");
receive_AT(RXbuff);
send_AT("AT\r\n");
receive_AT(RXbuff);
send_AT("AT+IPR=9600\r\n");
receive_AT(RXbuff);
send_AT("AT+ECHARGE=1\r\n");
receive_AT(RXbuff);
send_AT("AT+CBC\r\n");
_delay_ms(2000);
receive_AT(RXbuff);
send_AT("AT+CSQ\r\n");
_delay_ms(2000);
receive_AT(RXbuff);
}
So, the problem didn't have to do with this part of the code. I am using an emulated serial port to print stuff from the micro-controller to the PC. The issue was that the rate with which I was printing a char to the PC was much faster than what the PC was receiving, that's why some parts didn't appear.

Arduino Variable size Array Declaration

I get an error while trying to run the following code:
int SizeOfReadArray = 10;
int PacketLength = 5;
unsigned char rmessage[SizeOfReadArray];
unsigned long flag = 0;
unsigned char DataPacket[PacketLength];
int alternate = 1;
int remaining;
int Index;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
}
void loop() {
PacketExtraction();
}
void PacketExtraction(){
// Read Serial Buffer store in array
Serial.readBytes(rmessage,SizeOfReadArray);
// onetime execution for getting exact message from serial buffer
if (flag == 0){
for (int j=0;j<SizeOfReadArray;j++){
// check for start of packets through header bytes
if (rmessage[j+0] == 65 && rmessage[j+1] == 65){
// store the Index for extracting packet from message array
Index = j;
remaining = SizeOfReadArray-Index+PacketLength;
flag = 1;
}
}
}
// actual packet extraction
/* take PacketLength of data from serial burffr and store the rest
for remaining bytes for next data packet construction */
if (alternate == 1){
for (int k=0;k<5;k++){
DataPacket[k]=rmessage[k+Index];
}
// storing remaining bytes form next execution
unsigned char previouspacket[remaining];
for (int k=0;k<remaining;k++){
previouspacket[k] = rmessage[k+Index+PacketLength];
}
alternate = 0;
}
/* now this time take the previously saved remaining bytes of packet
and merge them with the current packet data */
else{
for (int k=0;k<remaining;k++){
DataPacket[k] = previouspacket[k];
}
for (int k=0;k<(remaining+1);k++){
DataPacket[k+remaining] = rmessage[k];
}
alternate = 1;
}
}
Error Message:
Arduino: 1.6.1 (Windows 7), Board: "Arduino Mega or Mega 2560,
ATmega2560 (Mega 2560)"
sketch_apr04b.ino: In function 'void PacketExtraction()':
sketch_apr04b.ino:52:23: error: 'previouspacket' was not declared in
this scope
Error compiling.
This report would have more information with "Show verbose output
during compilation" enabled in File > Preferences.
previouspacket is only declared in the first branch of the if…then blocks.
You should move unsigned char previouspacket[remaining]; before the if statement

USART embedded C. trigger character to store array

USART embedded c for atmega328p. trying to store an array of 10 characters of whatever user inputs after a certain character is received(in my case char $). This compiles for me but only outputs dollar signs when I input a string of chars using hercules utility reader. any help appreciated
the following is a copy of the code I am using
#define FOSC 16000000 // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
#include <avr/io.h>
//#include <stdio.h>
char trig='$';
char arr[10];
//This function is used to initialize the USART
//at a given UBRR value
void USARTInit(unsigned int ubrr)
{
//Set Baud rate
UBRR0H = (ubrr>>8);
UBRR0L = ubrr;
//Enable The receiver and transmitter
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
// Set fram format: 8data 2stopBit
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
//This function is used to read the available data
//from USART. This function will wait untill data is
//available.
unsigned char USARTReadChar( void )
{
//Wait untill a data is available
while(!(UCSR0A & (1<<RXC0)))
{
//Do nothing
}
//Now USART has got data from host
//and is available is buffer
return UDR0;
}
//This function writes the given "data" to
//the USART which then transmit it via TX line
void USARTWriteChar(unsigned char data)
{
//Wait untill the transmitter is ready
while(!(UCSR0A & (1<<UDRE0)))
{
//Do nothing
PORTD ^= 1 << PINB2;
}
//Now write the data to USART buffer
UDR0 = data;
}
int main(void)
{
DDRB |= 1 << PINB2;
//Varriable Declaration
char data;
USARTInit(MYUBRR);
//Loop forever
while(1)
{
//Read data
data = USARTReadChar();
int i =0;
//if incoming data is a dollar sign(trig),
if(data==trig)
{
//start a loop to collect data from buffer
for(i=0;i<10;i++)
{
//array has 10 elements, will fill up the ith element as per for loop
arr[i]=data;
// printf("arrayoutput %c\n",arr[i]);
USARTWriteChar(data);
}
}
}
}
I edited the while loop as suggested by oleg but still cannot get it to return the array .the entire code is as follows:
#define FOSC 16000000 // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
#include <avr/io.h>
#include <stdio.h>
char trig='$';
char arr[10];
//This function is used to initialize the USART
//at a given UBRR value
void USARTInit(unsigned int ubrr)
{
//Set Baud rate
UBRR0H = (ubrr>>8);
UBRR0L = ubrr;
//Enable The receiver and transmitter
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
// Set fram format: 8data 2stopBit
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
//This function is used to read the available data
//from USART. This function will wait untill data is
//available.
unsigned char USARTReadChar( void )
{
//Wait untill a data is available
while(!(UCSR0A & (1<<RXC0)))
{
//Do nothing
}
//Now USART has got data from host
//and is available is buffer
return UDR0;
}
//This function writes the given "data" to
//the USART which then transmit it via TX line
void USARTWriteChar(unsigned char data)
{
//Wait untill the transmitter is ready
while(!(UCSR0A & (1<<UDRE0)))
{
//Do nothing
PORTD ^= 1 << PINB2;
}
//Now write the data to USART buffer
UDR0 = data;
}
int main(void)
{
DDRB |= 1 << PINB2;
//Varriable Declaration
char data;
USARTInit(MYUBRR);
//Loop forever
//Read data
char input[10];
while(1){
data = USARTReadChar();
if(data == trig){
for(int i = 0; i < 10; i++){
//here we're saving 10 characters to input array
input[i] = USARTReadChar();
USARTWriteChar(input[i]);//tested without this also
}
}
}
}
Try to read chars in for() loop:
char input[10];
while(1){
data = USARTReadChar();
if(data == trig){
for(int i = 0; i < 10; i++){
//here we're saving 10 characters to input array
input[i] = USARTReadChar();
}
/* UPD: write stored array to console */
for(int i =0; i < 10; i++){
USARTWriteChar(input[i]);
}
/* those symbols are needed to emulate Enter button */
USARTWriteChar('\r');
USARTWriteChar('\n');
}
}
UPD: this code does exactly that you asked. It stores 10 chars in memory. To return them to console (utility reader) you have to use USARTWriteChar().

audio delay making it work

I am trying to implement a simple audio delay in C.
i previously made a test delay program which operated on a printed sinewave and worked effectively.
I tried incorporating my delay as the process in the SFProcess - libsndfile- replacing the sinewave inputs with my audio 'data' input.
I nearly have it but instead of a clean sample delay I am getting all sorts of glitching and distortion.
Any ideas on how to correct this?
#include <stdio.h>
#include </usr/local/include/sndfile.h>//libsamplerate libsamplerate
//#include </usr/local/include/samplerate.h>
#define BUFFER_LEN 1024 //defines buffer length
#define MAX_CHANNELS 2 //defines max channels
static void process_data (double *data, double*circular,int count, int numchannels, int circular_pointer );
enum {DT_PROGNAME,ARG_INFILE,ARG_OUTFILE,ARG_NARGS, DT_VOL};
int main (int argc, const char * argv[])//Main
{
static double data [BUFFER_LEN]; // the buffer that carries the samples
double circular [44100] = {0}; // the circular buffer for the delay
for (int i = 0; i < 44100; i++) { circular[i] = 0; } // zero the circular buffer
int circular_pointer = 0; // where we currently are in the circular buffer
//float myvolume; // the volume entered by the user as optional 3rd argument
SNDFILE *infile, *outfile;
SF_INFO sfinfo;
int readcount;
const char *infilename = NULL;
const char *outfilename = NULL;
if(argc < ARG_NARGS) {
printf("usage: %s infile outfile\n",argv[DT_PROGNAME]);
return 1;
}
//if(argc > ARG_NARGS) {
//
// myvolume = argv[DT_VOL];
//};
infilename = argv[ARG_INFILE];
outfilename = argv[ARG_OUTFILE];
if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))
{printf ("Not able to open input file %s.\n", infilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
};
if (! (outfile = sf_open (outfilename, SFM_WRITE, &sfinfo)))
{ printf ("Not able to open output file %s.\n", outfilename) ;
puts (sf_strerror (NULL)) ;
return 1 ;
} ;
while ((readcount = sf_read_double (infile, data, BUFFER_LEN)))
{ process_data (data, circular, readcount, sfinfo.channels, circular_pointer) ;
sf_write_double (outfile, data, readcount) ;
};
sf_close (infile) ;
sf_close (outfile) ;
printf("the sample rate is %d\n", sfinfo.samplerate);
return 0;
}
static void process_data (double *data, double *circular, int count, int numchannels, int circular_pointer) {
//int j,k;
//float vol = 1;
int playhead;
int wraparound = 10000;
float delay = 1000; // delay time in samples
for (int ind = 0; ind < BUFFER_LEN; ind++){
circular_pointer = fmod(ind,wraparound); // wrap around pointer
circular[circular_pointer] = data[ind];
playhead = fmod(ind-delay, wraparound); // read the delayed signal
data[ind] = circular[playhead]; // output delayed signal
circular[ind] = data[ind]; // write the incoming signal
};
//volume
/*for (j=0; j<numchannels; j++) {
for (k=0; k<count; k++){
data[k] = data[k]*-vol;*/
//}printf ("the volume is %f", vol);
return;
}
There are a few issues with your code that are causing you to access out of your array bounds and to not read\write your circular buffer in the way intended.
I would suggest reading http://en.wikipedia.org/wiki/Circular_buffer to get a better understanding of circular buffers.
The main issues your code is suffering:
circular_pointer should be initialised to the delay amount (essentially the write head is starting at 0 so there is never any delay!)
playhead and circular_buffer are not updated between calls to process_data (circular_buffer is passed by value...)
playhead is reading from negative indices. The correct playhead calculation is
#define MAX_DELAY 44100
playhead++;
playhead = playhead%MAX_DELAY;
The second write to circular_buffer at the end of process_data is unnecessary and incorrect.
I would strongly suggest spending some time running your code in a debugger and closely watching what your playhead and circular_pointer are doing.
Mike
At least one problem is that you pass circular_pointer by value, not by reference. When you update it in the function, it's back to the same value next time you call the function.
I think you are on the right track, here, but if you want something that's structured a bit better, you might also want to checkout this answer:
how to add echo effect on audio file using objective-c
delay in sample can be put as 100 ms would be sufficient

Resources