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.
I'm working in the communication of a PIC18F4550 and the PC with a pair of xBEE S2C. And
I am using xc8 to compile the code.
I send some characters to the PIC from the PC with an Xbee then I send a '/r', and the PIC has to return me the characters that I sent.
It works for 9 iterations, then it crashes. The image shows the
Serial Console (red characters are the response of the PIC).
I´ve tried resetting the EUSART but this doesn´t seem to work. Always fails at the 9th iteration. I´ve read some posts of OERR and I tried a lot of things but nothing has solved my problem.
EDIT: ***NOTE: This Error presents if the transmit interval of the package is
less than 1500 ms. And I need to transmit at least every 300ms.
Someone has an idea of what could it be?
Thanks
#define _XTAL_FREQ 8000000
volatile char bufferRx[60];
volatile char bufferTx[60];
volatile char dum;
int RxFlag,ContRx, ContTx;
void interrupt isr()
{
if(RCSTAbits.OERR)
{
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
x = RCREG;
if(x== 13)
{
bufferRx[ContRx] = x;
RxFlag=1;
}
else
{
bufferRx[ContRx] = x;
}
ContRx++;
}
void main(void)
{
//////////////////////////////////////////////////////////////////
//CONFIGURACIONES
//OSCILLATOR
OSCCONbits.IRCF= 0b111;
OSCCONbits.SCS=0b10;
//PORTS
PORTB = 0;
TRISB=1;
TRISC=0b10000000;
//INTERRUPTIONS
INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
PIE1bits.RCIE=1;
PIE1bits.TXIE=0;
PIR1bits.RCIF=0;
//RCSTA TXSTA
RCSTAbits.SPEN=1;
RCSTAbits.RX9=0;
RCSTAbits.CREN=1;
TXSTAbits.BRGH=0;
TXSTAbits.SYNC=0;
TXSTAbits.TXEN = 1;
TXSTAbits.TX9=0;
//BAUDRATE BAUDCON
BAUDCONbits.ABDEN = 0;
BAUDCONbits.WUE = 0;
BAUDCONbits.TXCKP = 0;
BAUDCONbits.RXCKP = 0;
BAUDCONbits.BRG16=0;
SPBRG=51;
//////////////////////////////////////////////////////////////////
while(1)
{
while(RCSTAbits.FERR)
{
dum = RCREG;
}
if(RCSTAbits.OERR)
{
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
ContTx=0;
if(RxFlag==1)
{
for(int x=0;x<ContRx;x++)
{
bufferTx[x] = bufferRx[x];
TXREG=bufferTx[x];
while(TXSTAbits.TRMT==0);
{
__delay_ms(1);
bufferTx[x]= 00;
bufferRx[x]= 00;
}
ContTx++;
}
RxFlag=0;
ContRx=0;
}
}
}
You are not using the "volatile" keyword anywhere although you are modifying some globals inside the ISR and using them outside.
This one below i make new code for pic32mx230 SPI module harmony design i need to send 96 bytes
register values and every 3 bytes starting CS will Low to High can anyone help
us where i am wrong?
`APP_DATA appData;
static uint8_t __attribute__ ((aligned (8))) app_spi_tx_buffer[128] =0xD4,0x1E,
0x00
0xD4,0x1D,0x80,\
0xD4,0x1C,0x09,\
0xD4,0x1B,0x00,\
0xD4,0x1A,0x00,\
0xD4,0x19,0x64,\
0xD4,0x18,0x18,\
0xD4,0x17,0x00,\
0xD4,0x16,0x80,\
0xD4,0x15,0x00,\
0xD4,0x14,0x00,\
0xD4,0x13,0x00,\
0xD4,0x12,0x00,\
0xD4,0x11,0x00,\
0xD4,0x10,0x00,\
0xD4,0x0F,0x00,\
0xD4,0x0E,0x80,\
0xD4,0x0D,0xE8,\
0xD4,0x0C,0x18,\
0xD4,0x0B,0x00,\
0xD4,0x0A,0x01,\
0xD4,0x09,0xF0,\
0xD4,0x08,0x00,\
0xD4,0x07,0x00,\
0xD4,0x06,0x53,\
0xD4,0x05,0x00,\
0xD4,0x04,0x01,\
0xD4,0x03,0x04,\
0xD4,0x02,0xAA,\
0xD4,0x01,0xAA,\
0xD4,0x00,0xAB,\
0xD4,0x1B,0x00,\
0xD4,0x1D,0x81};
void Modulator_SPI_Enable ( void )
{
MOD_SPI_CS_SELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN); //start clock from here
TIME_DelayUs(1);
MOD_SPI_CS_DESELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
TIME_DelayUs(1);
MOD_SPI_CS_SELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN); //start clock from here
TIME_DelayUs(1);
MOD_SPI_CS_DESELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
TIME_DelayUs(1);
MOD_SPI_CS_SELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
TIME_DelayUs(1);
MOD_SPI_CS_DESELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
TIME_DelayUs(1);
MOD_SPI_CS_SELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
TIME_DelayUs(1);
MOD_SPI_CS_DESELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
TIME_DelayUs(1);
TIME_DelayMs(20);
}
/* state machine for the SPI */
static void SPI_Task(void)
{
unsigned char i;
/* run the state machine here for SPI */
switch (appData.spiStateMachine)
{
default:
case APP_SPI_STATE_START:
/* set the state to 'wait' early so that the interrupt doesn't
finish fast and write the state and then is overwritten */
appData.spiStateMachine = APP_SPI_STATE_WAIT;
MOD_SPI_CS_DESELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN); //start clock from here
for (i=0; i<3; i++)
{
app_spi_tx_buffer[i];
MOD_SPI_CS_SELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
}
appData.drvSPIBufferHandle = DRV_SPI_BufferAddWrite(appData.handleSPI0,
app_spi_tx_buffer, sizeof(app_spi_tx_buffer),
0, 0);
if (DRV_SPI_BUFFER_HANDLE_INVALID == appData.drvSPIBufferHandle)
{
/* try again if we get a bad handle */
appData.spiStateMachine = APP_SPI_STATE_START;
}
break;
case APP_SPI_STATE_WAIT:
{
if ( DRV_SPI_BufferStatus(appData.drvSPIBufferHandle) & DRV_SPI_BUFFER_EVENT_COMPLETE)
{
appData.spiStateMachine = APP_SPI_STATE_DONE;
}
}
break;
case APP_SPI_STATE_DONE:
break;
}
}
void APP_Initialize ( void )
{
/* Place the App state machine in its initial state. */
appData.state = APP_STATE_INIT;
Modulator_SPI_Enable();
MOD_SPI_CS_DESELECT(SPI_SLAVE_2_CS_PORT_ID,SPI_SLAVE_2_CS_PORT_PIN);
TXDIS_DSELECT();
MOD_SPI_CS_SELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN); // CS will be low
appData.handleSPI0 = DRV_HANDLE_INVALID;
/* TODO: Initialize your application's state machine and other
* parameters.
*/
}
void APP_Tasks ( void )
{
/* Check the application's current state. */
switch ( appData.state )
{
/* Application's initial state. */
case APP_STATE_INIT:
{
bool appInitialized = true;
if (DRV_HANDLE_INVALID == appData.handleSPI0)
{
appData.handleSPI0 = DRV_SPI_Open(0, DRV_IO_INTENT_WRITE);
appInitialized &= (DRV_HANDLE_INVALID != appData.handleSPI0);
}
if (appInitialized)
{
/* initialize the SPI state machine */
appData.spiStateMachine = APP_SPI_STATE_START;
appData.state = APP_STATE_SERVICE_TASKS;
}
break;
}
case APP_STATE_SERVICE_TASKS:
{
/* run the state machine for servicing the SPI */
SPI_Task();
break;
}
/* TODO: implement your application state machine.*/
/* The default state should never be executed. */
default:
{
/* TODO: Handle error in application's state machine. */
break;
}
}
}
Thanks
Nome
Sometimes the best answer is the simplest:
unsigned char buff={0xD4,0x04,0x03,0x02,0x01,0x1E};
unsigned char i;
SPI1CON = 0x8020; // SPI on and SPI Master see 61106G.pdf PIC32 FRM
for(i = 0; i < 6; i++)
{
/* CS = HIGH */
SPI1BUF=buff[i];
while(SPI1STATbits.SPIBUSY);
// read the SDI line
unsigned char x = SPI1BUF;
/* CS = LOW */
}
You'll need to choose the right SPIXCON for the SPI bus you are attached to in your schematic.
EDIT:
I will not do you project for you, here is my example with a bit more example code.
unsigned char buff[128]={0xD4,0x04,0x03,0x02,0x01,0x1E.....};
unsigned char i;
SPI1CON = 0x8020; // SPI on and SPI Master see 61106G.pdf PIC32 FRM
unsigned char j = 0;
for(i = 0; i < 128; i++)
{
/* CS = HIGH */
if (j == 0)
MOD_SPI_CS_DESELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
SPI1BUF=buff[i];
while(SPI1STATbits.SPIBUSY);
// read the SDI line
unsigned char x = SPI1BUF;
if ( j == 2)
{
j = 0;
MOD_SPI_CS_SELECT(SPI_SLAVE_1_CS_PORT_ID,SPI_SLAVE_1_CS_PORT_PIN);
}
else
j++;
/* CS = LOW */
}
I have faced a problem connected with GPIO interrupt.
The task is to make a simple UI interface, so I need to use 3 buttons.
The problem is that I don't understand how to use GPIO interrupt for different pins and all my buttons work the same way.
here is the code:
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int value; // the actual value which is used in the module
char string[16]; // string that is printed in LCD for user
} UI_ELEMENT;
#define FIRST_LEVEL 3
#define SECOND_LEVEL 3
#define PWM 0
#define PGA 1
#define ADC 2
#define PWM_STATE 0
#define PWM_PERIOD 1
#define PWM_WIDTH 2
#define PWM_STATE_OFF 0
#define PWM_STATE_ON 1
volatile int buttonRightPressed = 0;
#pragma interrupt_handler buttonRightInt
void buttonRightInt(void){
// disable button interrupt
M8C_DisableIntMask(INT_MSK0, INT_MSK0_GPIO);
buttonRightPressed = 1;
}
void initialize_LCD(void){
LCD_Position(0,0);
LCD_PrCString("PWM");
LCD_Position(1,0);
LCD_PrCString("< select >");
}
void update_LCD(int* lvl1){
if (*lvl1 == PWM || *lvl1 == 3){
LCD_Position(0,0);
LCD_PrCString("PWM");
*lvl1 = 0;
}
else if (*lvl1 == PGA){
LCD_Position(0,0);
LCD_PrCString("PGA");
}
else if (*lvl1 == ADC){
LCD_Position(0,0);
LCD_PrCString("ADC");
}
}
void main(void)
{
UI_ELEMENT userInterface[FIRST_LEVEL][SECOND_LEVEL];
int level_1_steper = PWM;
int i;
M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
PWM8_EnableInt();
LCD_Start();
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);
initialize_LCD(); // set 'PWM' for upper row, '< select >' for lower row
while (1){
if (buttonRightPressed == 1){
for ( i = 0; i < 350; i++);
level_1_steper++;
update_LCD(&level_1_steper);
buttonRightPressed = 0;
// enable button interrupt again
M8C_EnableIntMask(INT_MSK0, INT_MSK0_GPIO);
}
}
}
Problem resolved! As usually solution is quite simple: use GPIO interrupt but test which button has been pressed. GPIO iterrupt:
void buttonInt(void){ // disable button interrupt
M8C_DisableIntMask(INT_MSK0, INT_MSK0_GPIO);
if (Right_Data_ADDR & Right_MASK) buttonRightPressed = 1;
if (Left_Data_ADDR & Left_MASK) buttonLeftPressed = 1;
if (Select_Data_ADDR & Select_MASK) buttonSelectPressed = 1;
}
I want to write 2 programs with C , one work on Robot1, the other work on Robot2.
So I want the program to send a signal from Robot1 via Bluetooth to Robot2 and Robot2 handles and accepts this signal (message)and reply to Robot1.
how to code this?
please I need any kind of help.
API OF my Robots:
/* function for serial communication */
void SerWrite(unsigned char *data,unsigned char length)
{
unsigned char i = 0;
UCSRB = 0x08; // enable transmitter
while (length > 0) {
if (UCSRA & 0x20) { // wait for empty transmit buffer
UDR = data[i++];
length --;
}
}
while (!(UCSRA & 0x40));
for (i = 0; i < 0xFE; i++)
for(length = 0; length < 0xFE; length++);
}
void SerRead(unsigned char *data, unsigned char length,unsigned int timeout)
{
unsigned char i = 0;
unsigned int time = 0;
UCSRB = 0x10; // enable receiver
/* non blocking */
if (timeout != 0) {
while (i < length && time++ < timeout) {
if (UCSRA & 0x80) {
data[i++] = UDR;
time = 0;
}
}
if (time > timeout) data[0] = 'T';
}
/* blocking */
else {
while (i < length) {
if (UCSRA & 0x80)
data[i++] = UDR;
}
}
}
-------------------------------------------------------------------------------------------Bluetooth Model...code...
#include "asuro.h"
void Sekunden(unsigned int s) //Unterprogramm für Sekundenschleife (maximal 65s)
{
unsigned int t; // Definierung t als Vorzeichenloses int
for(t=0;t<s*1000;t++) // 1000*s durchlaufen
{
Sleep(72); // = 1ms
}
}
int main (void)
{
unsigned char daten[2], merker=0; //Speicher bereitstellen, merker für start/stop
Init();
UBRRL = 0x67; //4800bps # 8MHz
Marke: // Endlosschleife
SerRead(daten,1,0); // Daten einlesen
switch (daten[0]) //und verarbeiten
{
case 0x38: MotorDir(FWD,FWD); // Vorwärts
MotorSpeed(merker*120,merker*120);
SerWrite("Vor \r",22);
break;
case 0x36: MotorDir(FWD,FWD); // Links
MotorSpeed(merker*120,merker*170);
SerWrite("Links \r",22);
break;
case 0x37: MotorDir(RWD,RWD); // Rückwärts
MotorSpeed(merker*120,merker*120);
SerWrite("Zurueck \r",22);
break;
case 0x34: MotorDir(FWD,FWD); // Rechts
MotorSpeed(merker*170,merker*120);
SerWrite("Rechts \r",22);
break;
case 0x35: if(merker==1)
{
MotorDir(FREE,FREE);// Stop
MotorSpeed(0,0);
SerWrite("Stop \r",22);
merker=0;
break;
}
else
{
MotorDir(FWD,FWD);// Start
MotorSpeed(120,120);
SerWrite("Start \r",22);
merker=1;
break;
}
}
i want to run this programm on my Robot.
Robot 2 needs to call SerRead with, lets say, a pointer to an empty buffer (length one or so), length one and zero as timeout. Afterwards, let it call SerWrite with a pointer to your buffer and length one.
Robot 1 should first call SerWrite with one byte of data and then wait for the result of a call to SerRead.