LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Arduino ADC/Serial corrupting data

Solved!
Go to solution

Hi everyone,

 

I hava an Arduino DUE and I have to generate a PWM to drive sensors, acquire data with ADC and then send to LabVIEW. 

I have a problem while reading from Arduino and/or transmitting via Serial, during one or both steps my data are "corrupted". I tested the PWM wave both with Arduino ADC and with NI 6008. I found that with the 6008 my square wave was quite clean while with Arduino , it was totally wrong. 

 

I do not know if the probelm is my LabVIEW file or ADC itself or even communication via serial, I have not even figured out yet what is the cause of  the problem, for this reason I ask you if someone knows what may be and if can help me.

 

I attach my two waves (one with NI6008 and DAQ assistant and one with Arduino and the block diagram) and LabVIEW.

Thank you very much!

Download All
0 Kudos
Message 1 of 13
(3,176 Views)

What is the PWM frequency?

What is the sampling frequency?

How often do you transmit and what does the serial packet contain?

 

Can you show part of the sketch so we can see how you are attempting the acquisition and sending?

 

I suspect that the serial communications are the sticking point, but its a guessing game right now.

 

0xDEAD

0 Kudos
Message 2 of 13
(3,169 Views)

Thank you for your reply. Sorry, I forgot to attach the code.

PWM frequency is 525 Hz and Sampling with NI is 10Khz, while with Arduino I did not set a precise ADC frequency but I mesured it and it is 20KHz (each entire loop takes a bit less than 50us).

I am sending 2 values (the 2 read analog values) as uint16 at baud 460800 and as binary data.

 

#define PWMFreq  (525);
#define DutyCycle (0.66);
uint16_t val[2];
int16_t carrier = 0;
uint16_t RegPWM = 328125/PWMFreq;
uint16_t RegDT = (int) RegPWM*DutyCycle;

void setup() {
  
 Serial.begin(460800);
 while(!Serial);     
 pinMode(22, INPUT);
 
 REG_PMC_PCER1 |= PMC_PCER1_PID33;                 // Enable peripheral TC6 (TC2 Channel 0)
 REG_PIOC_ABSR |= PIO_ABSR_P26 | PIO_ABSR_P25;     // Switch the multiplexer to peripheral B for TIOA6 and TIOB6  
 REG_PIOC_PDR |= PIO_PDR_P26 | PIO_PDR_P25;        // Disable the GPIO on the corresponding pins

 REG_TC2_CMR0 = TC_CMR_BCPC_SET |                  // Set TIOB on counter match with RC0
                TC_CMR_ACPC_SET |                  // Set TIOA on counter match with RC0
                TC_CMR_BCPB_CLEAR |                // Clear TIOB on counter match with RB0
                TC_CMR_ACPA_CLEAR |                // Clear TIOA on counter match with RA0
                TC_CMR_WAVE |                      // Enable wave mode
                TC_CMR_WAVSEL_UPDOWN_RC |          // Count up with automatic trigger on RC compare !PHASE_CORRECT!
                TC_CMR_EEVT_XC0 |                  // Set event selection to XC0 to make TIOB an output
                TC_CMR_TCCLKS_TIMER_CLOCK4;        // Set the timer clock to TCLK4: /128 (MCK/128 = 84MHz/128 = 656250Hz)

 REG_TC2_RA0 = RegDT;                               // Load the RA0 register 66%DT 
 REG_TC2_RB0 = 0;                                   // Load the RB0 register : -- 
 REG_TC2_RC0 = RegPWM;                              // Load the RC0 register as 656250/RegPWM/2(per la phase-corr) = freqHz

 REG_TC2_CCR0 = TC_CCR_SWTRG | TC_CCR_CLKEN;       // Enable the timer TC6
 
 analogReadResolution(12);
 
}

void loop() {

//float srt = micros();
carrier = 2*digitalRead(22)-1;
val[0] = analogRead(A0);
val[1] = analogRead(A1);

Serial.write(val[0]);
Serial.write(val[1]);
}
0 Kudos
Message 3 of 13
(3,162 Views)

Most likely, you are just reading your data out of sync.  As I told you in your other thread, you need a true message protocol to avoid this kind of issue (ie make sure you have a complete message).  When sending your data, first send a 0x2 (in ASCII, this means Start Text).  Then send your two data points followed by a checksum.  The checksum can be something as simple as adding all of the data bytes in your message, resulting in a U8.  Then on the LabVIEW side, you just read 1 byte until you read that start byte.  Then read 5 bytes (2 I16s and the checksum byte).  Add the data bytes together (Add Array Elements) and verify it matches the checksum byte.  If it does, process the data as you already are doing.  If not, don't process and go back to looking for the start byte.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 4 of 13
(3,133 Views)

Thank you for the reply, but I do not know how compare my first "read buffer" with the start of text I am sending. I know I have to use "equal?" block, but inputs of that block  are read buffer from the visa and... the string "STX"? The hexadecimal number 0x02? Its decimal form? 

 

Then I have a question for the sync, If I read something wrong, I am losing the entire data for that loop, is there a way to avoid it?

Here is what I am doing. Actually, I do not know if it is good ( the "equal?" of the STX is not connected).

 

Thank you for your time

 

 

0 Kudos
Message 5 of 13
(3,114 Views)

I am intrigued by the 480600 BAUD. Whats the story with that? Do the devices at both ends support it?

 

Crossrulz suggestion of making a packet structure is always a good one if you can tolerate the overhead.

 

Also, I'm not convinced that you can send 16 bit values using Serialwrite. I suspect it will truncate to 8 bits as it expects either a byte or a string.

 

I would try something like the below, see if it helps:

 

Serial.write(val[0] >> 8);
Serial.write(val[0]);

Serial.write(val[1] >> 8);
Serial.write(val[1]);

 

0xDEAD

 

 

Edited to add: I can't view your VI as I am on 2015 here. If you could re-save for my previous version I will happily take a look.

 

 

Message 6 of 13
(3,111 Views)

The baud rate is due to the fact that I have to send at the highest rate which does not generate garbage, I tested it via ASCII print and it transmits "correct numbers", and the exact baudrate is that I tested using TeraTerm and it has preset values, and 460800 was the highest among those.

 

About Serial.write, you are right about that but it did not solved the problem, I am trying to set the protocol but I am stuck. I attach the .vi for previous versions, let me know if you can see it.

 

I have a question about the shifting in serial.write, am I sending my bytes like it was Big Endian?

 

Thank you.

0 Kudos
Message 7 of 13
(3,099 Views)

I cant open the VI (still says 2018).

 

The byte order in the received string would be big endian.

For example hex string 0FD00FD0 would be 4048 from AI0 and 4048 from AI1

 

0xDEAD

0 Kudos
Message 8 of 13
(3,094 Views)

I saved it for previous version 15, I hope it will be fine

0 Kudos
Message 9 of 13
(3,087 Views)

due.png

 

Something like this should prove if it works or not. Then you can add what you need later.

(Probably best to replace AI0 and AI1 indicator with charts).

 

0xDEAD

Message 10 of 13
(3,083 Views)