Continuous ADC-capture over UART (Atmega328P/Atmega2560)

Go To Last Post
44 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

My goal is to measure RC-receivers RSSI pin with atmega328p and send the Received signal strenght to computer using UART with the help of FT232.

The signal what I am measuring looks like this:

RSSI FROM RECEIVER

 

Signal always stays up about 500us and then drops to 0.7V for a while, but only after that I am interested of the signal level, becaus that is varying by the signal strenght.

 

EDIT: Signal is up when Rx is off. The Rx is turned on little earlier than Tx, so the 0.7 level is the noise level.

Then the Tx is turned on and the connection is so good that the level goes to zero, but if there is very bad connection the level will be closer to noise level. That is the simple explaining to the behavior, but it is lot more comlicated.

 

So I want to measure samples from the last period of signal and do some calculation for them, but my problem is how to trigger the ADC or should I use continous mode.

I was thinking could I put my signal also to Input Capture pin and with auto trigger start the adc when there is rising edge and then store only the data after 1ms-> 1.4ms.

 

Thank you in advance for your tips!

 

 

Last Edited: Tue. Jun 26, 2018 - 06:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sound like a rather bizarre way to give RSSI?!

 

surprise

 

Are you sure you're looking in the right/best place?

 

maenpaa wrote:
only after that I am interested of the signal level, because that is varying by the signal strength

So how, exactly, does it "vary by the signal strength" ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

It might help to know what radio your using!

Jim

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

also a link to any documentation you have.

 

eg, how do you know that this is the RSSI signal ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

is it a AM or FM signal?

Is it RSSI out from a radio chip ? (number please)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using Turnigy Hobby King 2.4Ghz 4Ch V2 Tx and  9X 2.4GHz 8Ch V2 Rx which both uses AMICCOM A7105 chip. I have measured the RSSI straight from the RSSI pin from the RX A7105 Chip (Pin 1 as the datasheet says).

 

 

Last Edited: Thu. Jun 21, 2018 - 06:58 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You will need to low pass filter the signal, the modulation give some noise to the signal.

 

Add:

Or is this two radio's that make a communication, where you just listen?

 

on 2.4GHz there is all kind of noise your radio will see so perhaps make a ring buffer there always sample and when you receive a correct packet then look in the buffer to see how good the signal was.   

Last Edited: Wed. May 23, 2018 - 02:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

looking at the DS link provided, it chip has a digital RSSI value available, why not use it?

The RSSI pin is intended to be connected to the AGC cap to provide a filtered AGC voltage to the IF stage in the RX, it's not meant to be used as an RSSI output.

The chip has an internal ADC to read the RSSI at the proper time and provide a digital value.

 

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

Last Edited: Wed. May 23, 2018 - 06:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for your replies.

I have do some more measurement and it is even compicated signal that I thought. The radio is frequency hopping and the frame I have took picture is just one frame and there is 16 frames which can be little bit different.

My best measurement way at this far is the average minumum value that is about 30mV when very close, 40mV when 10m away and 400mV when 100m away and when the Tx is out of the range the signal changes totally.

There are two main types of frames and I have to figure out why they are like that.

 

Also to the digital RSSI value, it would be useful but it is hard to get out from the A7105 chip.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also to the digital RSSI value, it would be useful but it is hard to get out from the A7105 chip.

Not any harder than sending and receiving data, and certainly easier than burning CPU cycles doing signal processing. Show us the code/library you're using and we'll help out.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Can't help wondering if BER is a much more important indicator of (digital) signal condition than signal strength? (certainly is in other digital radio systems such as satellite TV reception). I'll bet the chip has registers for bit error rate too.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello and thank you for your solutions!

 

BER would be also good but I will be staying RSSI for now. The chip is very small and I was not able to solder straight to the chips legs anything so even that restrict my actions. Luckily the RSSI pin was soldered to the capasitor where I managed solder the wire. I have done much more measurement and got some new information about the behavior of Tx and Rx and the RSSI signal.

 

I desided to use continous mode ADC and send the raw data straight  to computer and then do the calculating by computer.

 

Last Edited: Thu. Jun 21, 2018 - 07:03 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello
Now I have got the program working. Now it is continous saving ADC values to 'ringbuffer' and when matlab calls values, it stops the ADC saving and sends the buffer to matlab.
After send is ready it continue saving data to buffer, but I need to wait until the buffer goes one round before I can call new values. Another option would be reading and saving data at the same time to the buffer, but I havent thought how it would work.
My code is based on Benn Thomsen Continuous ADC Capture code. My problem is that I am using atmega328P so I can have only 1024 bytes ringbuffer and for my apllication I have to use smallest sample rate, so I can get enough long sample in one buffer.

I think i will by Arduino Mega board so I can use larger ringbuffer and so on higher sample rate.

 

 

There is my AVR code if you are interested: (Badly commented)

/*
 * Hobbyking_buffer.c
 *
 * Created: 29.5.2018 14.42.03
 * Author: Miikka Mäenpää
 */ 

#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>

#define F_CPU 16000000UL
#define BAUDRATE 38400
#define BAUD_PRESCALER (((F_CPU / (BAUDRATE * 16UL))) - 1)
#define BUFFER_SIZE 1024
#define FALSE 0
#define TRUE 1

volatile uint16_t bufferIndex=0;
uint16_t i=0;
volatile uint8_t data[BUFFER_SIZE];
volatile uint8_t data_in = FALSE;

void adc_init(void);
void USART_init(void);
void USART_send( unsigned char data);
void Button_init(void);

int main(void){

	DDRB = (1 << PB0);
	PORTB |=  (1 << PB0);		//Turn off LED
	//PORTB &= ~(1 << PB0);		//Turn on LED
	//PORTB ^=  (1 << PB0);		//Change LED

	USART_init();
	adc_init();
	Button_init();
	sei();

	while(1){
		if (data_in)
		{	cli();
			USART_send((uint8_t)(bufferIndex >> 8));
			USART_send((uint8_t)(bufferIndex));

			for (i = 0; i < BUFFER_SIZE; i++)
			{
				USART_send(data[i]);
			}

			data_in = FALSE;

			sei();
		}

	}
}

ISR(ADC_vect){

	data[bufferIndex++] = ADCH;

	if (bufferIndex == BUFFER_SIZE)
	{
		bufferIndex = 0;
		PORTB ^=  (1 << PB0);		//Change LED

	}

}

ISR(USART_RX_vect)
{
	data_in = UDR0;
}

//Turn ADC on/off with external button
ISR(INT0_vect) {

	if (ADCSRA  & (1 << ADEN)) //if ADC on
	{
		ADCSRA &= ~(1 << ADEN); //Turn off ADC
		PORTB |=  (1 << PB0);	//Turn off LED
	}
	else
	{
		ADCSRA |= (1 << ADEN) | (1 << ADSC); //Turn on ADC
	}

}

void adc_init(void){

	//ADC prescaler = 128 -> ADC Clock =  125kHz
	ADCSRA = ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0));

	//Voltage reference to AREF (2.5V?), Left adjust result
	ADMUX = (1 << REFS0) | (1 << ADLAR);

	DIDR0 = 0xFF; //Disable digital input registers A0-7

	//Free runnig mode (13 ADC clock cycles per conversion -> ADC SPS 9.615k
	ADCSRB &= ~((1 << ADTS2) | (1 << ADTS1) | (1 << ADTS0));

	//Turn on ADC, Enable interrupts, enable autotrigger
	ADCSRA |= (1 << ADEN) | (1 << ADIE) | (1 << ADATE);
	ADCSRA |= (1 << ADSC); //start conversion
}

void USART_init(void){

	UBRR0 = BAUD_PRESCALER;
	UCSR0C = ((0<<USBS0)|(1 << UCSZ01)|(1<<UCSZ00)); // Set frame format
	UCSR0B |= (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0); // Enable receiver, transmitter and interrupt
}

void USART_send( unsigned char data)
{

	while(!(UCSR0A & (1<<UDRE0)));

	UDR0 = data;
}

void Button_init(void) {

	DDRD &= ~(1 << PD2);
	PORTD = (1 << PD2);

	EICRA = (1 << ISC01);	//Falling edge
	EIMSK = (1 << INT0);	//Enable INT0
}

  and MATLAB functions and code:

function [s] = Serial_Init(N)
instrreset

port = 'COM3';
s=serial(port,'BaudRate', 38400,'InputBufferSize',2*N);
fopen(s);
function Serial_close(s)
fclose(s);
instrfind
function [ voltage , buffer_index ] = Serial_READ(s,N)
fwrite(s,1)
data = fread(s,N+1,'uint8');
buffer_index = data(1);
voltage=data(2:end)*2.5/256;
end
clear all
clc
X=4;

V = zeros(X,1024);
V2 = zeros(X,1024);
N=1024;
Fs = 9.6154e3;
time = (0:N-1)./Fs;
s = Serial_Init(N);
pause(1)
buffer_index = zeros(X,1);
tic

for n = 1:X
    [V(n,:),buffer_index(n)] = Serial_READ(s,N);
    pause(0.200)
end
toc

for n =1:X
    V2(n,:) = V(n,[buffer_index(n)+1:end 1:buffer_index(n)]);
end

for n = 1:X
    figure(n)
    plot(time,V2(n,:),'-o')
    ax = gca;
    ax.XAxis.Exponent = -3;
    axis([0 1023/Fs 0 2.25])
    grid on
    xlabel('Time (ms)')
    ylabel('Amplitude')
end

Serial_close(s)

 

Last Edited: Thu. Jun 21, 2018 - 06:50 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

don't wire a pushbutton to an external interrupt! Maybe you've found out already that the button doesn't always work as expected. Pushbuttons bounce and give multiple interrupts per press. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes that's true Kartman, but the push button is rarely used in this project (I did it for fun, just so I can turn it off when I go to lunch laugh), so it does not matter much (And I can always check from the led is the ADC on or off. 

 

What does matter is when the buffer goes round, there is some strange happening, maybe few measures skipped. But I think I will consentrate on prosessing the data until I get my Ardruino Mega board.

 

By the way, I am using external VREF for ADC and I did it with voltage divider from the USB VCC with two 1Kohm resistor to get 2.5V. Is there a better way you suggest or is it "good enough"?

 

EDIT: I didnt wait enough time in matlab so the buffer didnt have time to go around.

Last Edited: Thu. May 31, 2018 - 11:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

Today I got my arduino Mega board and burnt my code there. (can be seen few post earlier)

I noticed mega has 4 USART so I had to rename ISR(USART_RX_vect) -> ISR(USART0_RX_vect), but I think other names should be the same.

My USART connection was not working and the ADC Didn't work.
 

Code should start continous ADC and ISR function saves the value to buffer and everytime buffer gets full, led will change state and ADC strats from the beginning of the buffer.

ISR(USART0_RX_vect) stores sata and if the data is 1 the buffer is send to USART

But I figured out with the led that code will never enter the ISR(ADC_vect) or ISR(USART0_RX_vect)?
 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

maenpaa wrote:
but I think other names should be the same.
I would not have thought a port from 328 to 2560 is as simple as changing the name of one ISR vect ! There's quite a lot different between those two chips so you need to look at every bit of every register of every peripheral you are using and find any change in behaviour and amend accordingly.

 

This is one of the many ways Arduino is "better" than plain C. It hides all the differences in "cores" so as long as you only call hardware adaption functions in the core it just works (and that can even involve a move from AVR to ARM!). as soon as you start hitting the silicon directly then when you move from one device to another you have to "port" any changes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah you are rght clawson that it is not so easy and It would have been easier to write whole thing new by arduino code, but I am not familiar with it so I tried plain C.

I have browsed the datasheets and there are many differences, but the basics and the names are pretty much the same. 2560 has little bit more possibilities in ADC but it has all the same register than 328, and pretty much same with the UART.
My biggest concern is, why any of my interrupts wont work frown

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"pretty much" the same is not good enough!

 

They need to be either exactly the same, or you have to do all the work to take care of all the differences.

 

My biggest concern is, why any of my interrupts wont work

Because you have missed something!

 

As ever, the best approach is probably to take it little-by-little, getting one small part to work at each step - rather than trying to port the entire thing in one go.

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If all the interrupts don't work it hints at a couple of possibilities (which might actually be the same thing):

 

1) the code path that holds the sei() is not being executed

 

2) a while() loop is holding execution infinitely somewhere

 

As I say (1) may simply be a consequence of (2)

 

Don't suppose you have access to an ICE?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Should the interrupt vector in dependies be the same as in datasheet?
Datasheet says ADC is vector 30 but in dependies is said #define ADC_vect            _VECTOR(29)

 

Datasheets first vector is reset vector, what is not in dependies, so every vector number is missmatched.

 

EDIT: I guess no because 328P has also different numbers

Last Edited: Wed. Jun 13, 2018 - 10:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

maenpaa wrote:
Should the interrupt vector in dependies be the same as in datasheet? Datasheet says ADC is vector 30 but in dependies is said #define ADC_vect _VECTOR(29) Datasheets first vector is reset vector, what is not in dependies, so every vector number is missmatched.
GCC headers choose 1-based, datasheet chooses 2 based (they are actually 1 based but they count "reset" as number 1). Doesn't really matter because the _VECTOR(n) is effectively "hidden". You refer to things like "INT0_vect" and only behind the scenes is this temporarily interrupted as _VECTOR(1)

 

The key thing is that the C compiler headers match this:

 

http://svn.savannah.gnu.org/view...

 

which has:

50 	        .section .vectors,"ax",@progbits
51 	        .global __vectors
52 	        .func   __vectors
53 	__vectors:
54 	        XJMP    __init
55 	        vector  __vector_1
56 	        vector  __vector_2
57 	        vector  __vector_3
etc.

 

Last Edited: Wed. Jun 13, 2018 - 12:09 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I kind of understood what you were saying clawson but I dont honestly know where my C-compilers headers are indecision I havent really explored enogh how the code actually is compiled and transformed and burned into chip surprise. I dont either have ICE

 

I have been testing simple codes for mega2560 and I figured out that once the interrupt should occur, the code jumps to start of main and continues until sei(); and jumps again into start.

Last Edited: Wed. Jun 20, 2018 - 09:40 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Until I get the interrupts working, I was wondering is it possible to continuously send ADC data to computer if my ADC samplerate is ~10k SPS. (I managed to do it by stopping the ADC for the time UART sends data, but afterwards I would be much better to transmit continous data)

 

I was going to use ring buffer to store the ADC data and send it to computer and I did some calculations if the samplerate would be 10k SPS and one sample is 8 bits and then there is 1 start and 1 stop bit so the frame is 10 bits. So the buffer to work I would need 10*10k = 100k Baud rate? and is that achievable easily?

 

(Arduino Mega R3 (atmega2560 (16MHz external clock) and atmega16U2 handling the UART) -> Matlab2017b(Lenovo T470p, Win 10))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

maenpaa wrote:
I have been testing simple codes for mega2560 and I figured out that once the interrupt should occur, the code jumps to start of main and continues
Almost certainly "catch all" described on this page in the manual:

 

https://www.nongnu.org/avr-libc/...

 

That is you have enabled some interrupt for which you have not provided an ISR() so it goes to "bad interrupt" which does a JMP 0 and restarts the AVR. This will happen as soon as you sei() and as soon as the interrupting event then occurs.

 

maenpaa wrote:
data to computer if my ADC samplerate is ~10k SPS.

If you send binary then it is 2 bytes for a reading (I assume 10 bit not 8 bit?). Each byte takes 11 bits with 8N1 framing so you need to send 22,000bps so any baud rate above that should allow you to do this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tested the "catch all" function but it didn't help. Added to my code:

ISR(BADISR_vect)
{
    PORTL |= (1 << PL2);	//Turn on GREEN LED
}

But still looping/jumping to main... even added ISR vectors to EMPTY_INTERRUPT(); but it didn't help. Tried to look for the dependencies files, but I didnt't find anything suspicious.

 

clawson wrote:
Each byte takes 11 bits with 8N1 framing

It is not relevant but why does it take 11 bits and not 10 bits?

clawson wrote:
(I assume 10 bit not 8 bit?)

Actually I take only 8 most signifigant bits of the ADC result to get data faster to computer.

 

EDIT: I got the interrupts working with arduino ide but don't like the program, so it would be nice coding with AS

Last Edited: Mon. Jun 25, 2018 - 08:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

8N1 is only 10 bits. If you set the serial to 115200 baud, then youcould achieve your data rate. Why did you need to fiddle with interrupts? The Serial driver should work with any fiddling.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:

The Serial driver should work with any fiddling.

What do you mean by serial driver?

I thought I would need ringbuffer, because my ADC sample rate is so high and thats why I thought I would need interrupts, but if I increase UART baudrate enough, would it be possible just polling the ADC result and always when it is ready, sending it via UART and forgetting interrupts and buffers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

maenpaa wrote:
because my ADC sample rate is so high

But clawson has shown that your sample rate is not particularly high - relative to common UART baud rates!

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also note that if you were close to the limit then it's actually more efficient to simply poll the thing and shove the bytes just as soon as UDRE. Using an interrupt introduces something like a 20..30 cycle overhead per byte for all the effort involved in getting into and out of an ISR.

 

Also the fact that you say 8 not 10 bits (which for UART really means 1 byte not 2) means that my estimate above was conservative - you can achieve double the rate if it is (effectively) half the amount of data to be transmitted.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

and, if you're close to the limit, you could be doing (or, at least, start) the ADC conversion while the UART is transmitting ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

" samplerate is ~10k SPS.

 

If you send binary then it is 2 bytes for a reading (I assume 10 bit not 8 bit?). Each byte takes 11 bits with 8N1 framing so you need to send 22,000bps"

Assuming kSPS is kilo sample per second

Assuming bps is bit per second

OP wants to sample at 1E4 sample per second, leading to 2*11 *1E4 = 220, 000 bits per second (2.2E5).

 

With a 200 uS sample period, https://balau82.wordpress.com/20...

computed a 80 000 baud rate (usual value 115200). But OP sampling rate seems twice faster ... (or 2 LSBs are useless : then 115200  are enough).

 

BTW binary sending is very difficult and unpleasant  to debug (PC does not "know" when data begin -and can make guesses about the part of the 16 bits word-; sending only 8 bits -dividing ADC value by 4-  can hide the need for synchronization).

Edited : read post 30 :115200 is conservative with 8 bits (one byte) transmission. I am afraid it is not enough with 2 bytes.

Last Edited: Mon. Jun 25, 2018 - 01:52 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
Each byte takes 11 bits with 8N1 framing

Close, 10 bits per character, 1 start + 8 data + 1 stop = 10 bits.

 

I'm sure that is what you meant!  wink

 

 

Jim

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No: I copied and pasted Clawson post #25, then recomputed with the same assumption (was 10 times overoptimistic if the way I read 10k SPS was right, a10% error could be neglected at this stage).

 

Balau (I linked to) made a more realistic calculation .

Last Edited: Mon. Jun 25, 2018 - 01:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dbrion0606 wrote:
PC does not "know" when data begin

But that also applies to text.

 

In both cases, you need some "overhead" to delimit values

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"

But clawson has shown that your sample rate is not particularly high - relative to common UART baud rates!

"

Well, if instead of quoting other people (making threads long and redundant, in a futile attempt to belittle OP ), one checked for *10 errors?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Edited : reply to #32

"

But that also applies to text."

 

Well, you missed a *10 error (if my interpretation of SPS is right)

text may begin at the next \n in simple (90%) trivial cases.

 

 

"In both cases, you need some "overhead" to delimit values"

Every one trying to transmit data knows it....

In the *special* case ADC always samples on the same channel, and only 8 MSBs are transmitted : one does not need overhead to transmit binary -this is a very special case; seems this exception  is this very topic...)

Last Edited: Mon. Jun 25, 2018 - 02:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, in the special case.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But it was this very topic (no need for googlology nor plussology)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you all for your replies and sorry for my unclear requirements. My ADC knowledge is quite poor and UART knowledge is even worse so correct me if I'm wrong.

 

With 10 kSPS I meant 1e4 samples per second as dbrion0606 said. Actually I have 16 MHz clock and the available ADC clock division factors are:

 

ADC_Division_factor

128 is just enough for me but it would be better to have faster (64).

ADC conversion take 13 ADC Clock cycles so my sample rates would be:

  • 16e6 / 128 / 13 = 9.615e3 Sample/second

  • 16e6 / 64 / 13   = 19.23e3 Sample/second

 

I think my Sample rate is more critical than the accuracy,

so thats why I left the 2 LSB out (and for make things simpler).

With 8N1 framing I could send one sample in one frame, using 10 bits.
So I would atleast need BaudRates (Minimum from the next table):

  • 115.2Kbps

  • 230.4Kbps

 

 

UART_BaudRate 

  I can see there is those error rates in the table

  so should I be worried about them?

  Considering I will be choosing 115.2Kbps, 230.4Kbps or 250Kbps

 

 

 

  Nice link btw dbrion0606 in the #32

 

  I think I will move back to my own made arduino UNO and

  give it a try if I can transimit ADC straight without buffer.

  (And at the same time I can move from IDE to Atmel Studio yes )

 

 

Last Edited: Tue. Jun 26, 2018 - 06:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is an issue with the 115.2kbps:

a) it has the "worst" error rate

b) it is the fastest baud rate a RPi/nanoPi can support (for very complicated reasons; there is a fix, but it might lead to nervous exhaustion if one finds it when one changes OS)

I always use this rate on arduino+nanoPi, and was never annoyed with point (a)

 

binary transmission has many drawbacks :

a) unless PC/xxPi sends a start signal, one does not know where it begins; only one 8 bit channel can be interfaced if start signal is not sent .... (with a start signal, more complicated data can be transmitted, but it is unpleasant to try to debug)

 

b) new versions of Arduino have curve plotter, which eats ASCII  (said to be nice)

 

c) ASCII coded values has a limited number of chars, allowing error detection. Binary transmission cannot detect horrors.

 

d) I bet I missed many others.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you did want 10 bits and accurate UART consider switching to a 11.0592MHz crystal. You can use a /64 ADC prescaler which then runs the ADC at 172.8kHz which makes the sample rate 13.292ksps and the UART is 100% accurate at 115,200. Of course if you do bump from 8 to 10 bits then you need to send 2 bytes each time (unless you wanted to pack the datastream?) so this halves the transmission bandwidth

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quite nice tip clawson yes I consider it and at the meanwhile try if I get it working somehow with the 16MHz crystal.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The odd thing about ADC and the prescale setting is that it often helps to REDUCE the CPU speed to get a "better" value. Obviously the goal is to get the clock as close to 200kHz as possible (though you may find that 16MHz/64 = 250kHz is OK). So you really want a crystal that is a binary multiple of 200kHz. 200kHz * 64 = 12.8MHz in fact. So a crystal of that frequency or perhaps half (6.4MHz) could be a good choice but you also have to weight that against the requirement of a fast/accurate UART speed. So the 11.0592MHz is possibly the best choice in the region of 12.8MHz.