Arduino Leonardo and Funduino Mega, frequency on analog read - arduino

I write a simple Arduino software where I read some information on analog pins.
I compile this software on an Arduino Leonardo and on a Funduino Mega. Anyway, the Arduino obtains a better sampling frequency. Did you think that I can improve the frequency performance if I buy an Arduino Mega?

The main difference is using on-chip USB interface on Arduino Leonardo. You can use baud rate settings, but it'll be ignored and it'll run as fast as it's possible.
On the other side, if you're using Mega 2560 with Serial.begin(9600); and for example Serial.println(analogRead(A0));, then it's not possible to get about theoretical 15000 samples per second as you can send only about 960 characters per second.
Btw: for three 8bit characters (for HEX representation, 4 characters for DEC representation), "\r\n" separator and 15000 samples/s you'll need baud rate about: 5*(1+8+1)*15000 = 750000 baud/s (8bit characters + 1 start bit + 1 stop bit)

Related

ZX Spectrum - Issue with RS232 (Serial Port)

I recently got hold of a ZX Spectrum +3 and am trying to get RS232 working with the spectrum. I’ve built a cable (‘BT’ style connector <-> DB9 serial) following the pin out of the cable (Spectrum 128 RS232 data cable) here.
The other end of the cable is connected to the PC using a USB-Serial adapter. I'm using Moserial on Linux to communicate with the Spectrum.
The cable works and I can use LLIST to print BASIC programs over the serial port, but I'm unable to get the Spectrum to read from the serial port reliably - even when enabling hardware handshaking (DTR/CTS) in Moserial.
I wrote a simple program in +3 BASIC to print received characters to the screen. It seems the first character is received OK, but the remaining characters are dropped or become corrupted.
Here is an example of what the Spectrum outputs when attempting to send 'zx spectrum' at 300 baud:
z[dot/box character]. VAL$ [box character]MOVE VAL$ VAL$ ?)
(it seems VAL$ and MOVE$ are each a single character in the Spectrum's ROM)
screenshot:
And the BASIC program which opens the serial port, and prints received characters to the screen:
10 FORMAT LINE 300
20 FORMAT LPRINT "r"
30 FORMAT LPRINT "e"
40 OPEN #4,"p"
50 PRINT INKEY$#4;
60 GO TO 50
I discovered that if I send characters one-by-one from the PC with a long enough delay between them, I can get a much more reliable output from the Spectrum. I tested this with different delays, and 80ms worked the best. I don't really want to use this approach as a solution - it's awfully slow and occasionally some characters are dropped.
Could this be an issue with the Spectrum itself? Or am I missing something in my setup? Something just doesn't seem right, I know there is a program loader for the spectrum over serial - so surely the spectrum must be able to accept serial input without a 80ms delay per character?
The ZX Spectrum Interface 1 works by bit-sampling, in a software loop, with delays, so that it can look for the start bit and then look for the other bits. There is no shift register. It's all done in software.They don't even use interrupts or some other kind of fixed external timer to generate baud rate delays.
As a result, it doesn't even start looking for a start bit until it knows you're looking for input... Now that you have an idea what's going on I'm pretty sure you've already seen the problem there? If you're sending data too fast, then your basic program doesn't even have time to go back to the receive routine to look for start bits, and start bits are going to be lost, or more likely, you're going to pick up a bit transition mid-byte and receive gibberish... So you need to make sure that there's a delay between bytes and your Spectrum is ready to receive the next byte before you start transmitting.
Hope this helps even though it's a while ago, but others will find this so...
In zx spectrum 48k, with interface 1, i must choose how the rs232 will work.
Mode t : text ->rx and tx only character in 7bit
Mode b: byte -> rx and tx full byte (8 bit)
Maybe you must chek that.
On 48k with interface 1
FORMAT "b";9600
Then , the spectrum works in 8bit data at 9600 bauds.
In your code, i dont see how will works.
My best regards.
I came across your problem as I was trying to do the same!
You need to enable RTS/CTS handshaking in your linux (PC) application, not DTR/RTS.
This works for me on my Spectrum+2:
100 REM ** Receive Test **
110 REM ** Use RTS/CTS **
120 CLS
130 FORMAT "p";9600
140 OPEN #4,"p"
150 PRINT INKEY$#4;
160 GO TO 150
There's software incompatibility between modern computers and ZX Spectrum when doing serial communication. It can be fixed, but not from Basic. The problem with RTS/CTS is that after Spectrum signals that it can't receive any more data via the CTS signal: modern UART chips will assume that the receiving computer is still able to receive cca. one buffer of data (=up to 32 bytes). But ZX Spectrum only has 1 byte buffer. So when Spectrum says its' full, it will get flooded by additional 32 bytes of data.
That is the reason anything faster then 1200 bauds will not work from BASIC. However ... I got ZX Spectrum to run reliably at 57600 and with error correction at 115200. By simply expecting up to 32 bytes after I signal the PC to stop sending data.
I've had all this working years ago with my Spectrum and the ZX Interface 1's own rs232 port, but I wrote some C program using an old Windows 386 computer.
I still have the hardware and the cables. In fact, now that I remember I had to build my own "null modem" cable and connect it from the RS232 port on the computer to the ZX Interface 1 (I have an old Sony Vaio laptop with an RS232 port).
I was even able to download TAP files to play on the real spectrum. I'll dig up what I have and get back to you.

Why arduino voltage read is higher when there is relay turned on (a load on a digital pin)

I am using arduino Uno to read voltage from A0 pin with simple 1/3 resister divider (5v applies to a voltage divider, and A0 gets 1/3 of 5v). There is a relay connected to D1 pin.
(My eventual goal is to measure 15v, that's why using voltage divider to diagnose the problem)
I noticed that when relay is on, the A0 read is higher than it should be. I am not sure what's the cause, and like to understand it.
Description about the circuit:
A0: analog pin used to measure voltage.
D1: a digital pin used to control a relay.
Resistor divider: R1 = 2k, R2 = 1k. R1 connects to 5v (arudino Uno 5v output). A0 is connected to R2, therefore, A0 should get 1/3 of 5v, which is 1.67v.
Few measurements to diagnose the problem:
Vmesaure_all: a manual voltage measure on R1 + R2.
Vmeasure_r1: a manual voltage measure on R2 only, which is input voltage of A0.
Vcode_r1_A0: arduino A0 analog read.
A)Relay is off:
Vmeasure_r1=1.67v (1.67 *3 = 5.01)
Vmesaure_all=5.03v
Vcode_r1_A0=339 (339 * 3 = 1017)
All above makes sense.
B) Relay is on:
Vmeasure_r1=1.63v (1.63 * 3 = 4.89v. OK. Makes sense as it is almost same as Vmesaure_all)
Vmesaure_all=4.91v (Relay is a load, it makes voltage drop on if measuring voltage of R1+ R2. I think it is expected)
Vcode_r1_A0=345 (why higher than 339, which is relay off A0 read???)
I could not explain this. If use this value to calculate voltage on R1 + R2, you will get higher voltage (the voltage to be measured), compared with relay off.
I would expect Vcode_r1_A0 to be < 339.
I did few experiments, andgot consistent behavior described above. Why?
Yes, the numbers can make sense. The analog to digital converter (ADC) by itself is not an absolute voltmeter. ADC's have a reference voltage and are calculating the digital value relative to that reference voltage. The Arduino provides you choice of reference voltage via the function analogReference()
The default behavior is that analog reference is the supply voltage pin, which is nominally 5.0 V. But that leads to your problem:
If Vcc changes while the analog input stays the same, the digital value changes.
If Vcc drops, the digital value will increase.
In other words, an ADC is only as accurate as its reference voltage.
The ATmega chips include a voltage reference that will not vary with Vcc. If you set the INTERNAL reference, then full scale 1024 digital is now 1.1 V.
analogReference(INTERNAL);
x = analogRead(A0);
// now x = 1024 is A0 = 1.1 V
Using this code, the digital value will be more accurate and not sensitive to Vcc. The tradeoff is that the full scale range is greatly reduced to only 1.1 V. To accommodate that reduced range, you need to add a voltage divider. Because you already intend to do that, you should use the internal reference and adjust the resistor values of your divider.
But, you are dropping Vcc by 0.1 V! Do you notice the chip is hot or a burning smell? Confirm that the current drawn by the relay coil is within the rating of the pin. Commonly, people use a transistor or driver chip (for example ULN2003) to power a relay load. Also beware that connecting inductive loads like relays and motors straight to digital pins tends to destroy those pins because of the flyback voltage when you turn off the coil.

What is the exact frequency of PWM signals produced from Arduino pins

In http://arduino.cc/en/Reference/analogWrite it says,
" The frequency of the PWM signal on most pins is approximately 490 Hz. On the Uno and similar boards, pins 5 and 6 have a frequency of approximately 980 Hz. Pins 3 and 11 on the Leonardo also run at 980 Hz. "
I want now to check that frequency. Simply I typed this command analogWrite(9,127), which will generate PWM signal with duty cycle 50%.
Then I used the pulseIn built-in Arduino function (pulseIn descriotion) and typed this command pulseIn(9,HIGH) to measre the period in which the signal is HIGH. It returns in average 1010 us.
So the period time is 2020 (1010 for the High period and 1010 for the low period) and consequently the PWM frequency from that pin is 495.04 ~ 495Hz.
The same is done with pin number 5. The High period is 506 uS, The full period is 1012 uS, The PWM frequency from that pin is 988.14 Hz ~ 988 Hz.
So, What is the exact PWM frequency ?!
The following pictures is snapshots for the Arduino sketch and the results
The Arduino sketch
When I pressed '1' multiple times
When I pressed '0' multiple times
PWM signals are created by timers. A timer increments a register, and various methods create a square signal based on that.
The frequency depends on 3 things:
the master clock: 8MHz or 16MHz usually on Arduino)
the prescale (or divisor on the page below): to slow down the frequency, you can setup the timer to increase the count every 1, 2, 4, 8, 16… master clock cycles
the maximum count: there are several counting methods, but an important limit is the register size (usually 8 bits and 16 bits on Arduino)
You'll find specific details on this page:
http://playground.arduino.cc/Main/TimerPWMCheatsheet
So, What is the exact PWM frequency ?!
imo There are to many variables to give the "exact" PWM frequency between boards and other factors.
For example, if I were to test two different boards from the same company I would not be able to get an exact match.
You've used one of the two pins where the PWM signal works at 980hz!
More specifically the pin 5 and 6!
This is what the website of Arduino says:
The frequency of the PWM signal on most pins is approximately 490 Hz.
On the Uno and similar boards, pins 5 and 6 have a frequency of
approximately 980 Hz.
http://arduino.cc/en/Reference/analogWrite

I need help reading analog voltages in an arduino mega2560

I'm new to microcontrollers and I need help reading voltages and printing them in the serial monitor. I have done this using a potentiometer, but I was wondering if I could do the same with just voltages. Below is the code that I used when I read the potentiometer values:
I have tried reading voltages but when I input a voltage smaller than between 3-5V in pin A0 I get 0s in the serial monitor
int potPin = 0; // select the input pin
int val = 0; // variable to store the value coming from the function generator
void setup()
{
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
val = analogRead(potPin); // read the value from the function generator
Serial.println(val);
delay(1000); //Sampling rate for the signal
}
as Udo Klein said, this looks like a hardware issue. try setting up your circuit like this: http://imgur.com/PYbeqLq
note that the grounds are shared between the function generator and the arduino - this is important for ensuring that voltages are measured correctly. remember that voltage is actually a difference in electric potential, so you need a common reference point to measure from.
To answer your question, yes you can read voltages from another piece of hardware.
As gearbot tells you it is important to keep a common ground between the arduino and the other piece of hardware.
Also be carefull, the arduino can only measure voltages between 0 and 5 Volts. Don't try to measure higher voltages without adjusting the circuitry as you might destroy your arduino board.
If you're unsure measure the voltages before attaching to the arduino with a multimeter.
The Uno has 6 analog inputs, labeled A0 through A5, each of which provide 10 bits of resolution (i.e. 1024 different values). By default they measure from ground to 5 volts, though is it possible to change the upper end of their range using the AREF pin and the analogReference() function.
edit:
I didn't see the added comment at the bottom of your post. This indicates indeed a hardware problem (probably in your circuitry)
To be sure the arduino does the right thing, measure the voltage with your multimeter between pin A0 and GND while your hardware is attached and working. You should be able to read the correct voltage there.
I suspect it will give the same values as the Arduino.
Then trace back your circuitry with your multimeter (keeping GND attached) to find where something is going wrong.
Try scaling your 0 to 5 or 1-5v input
using map function.
int setValue = map(ana1Value, 0, 1023, 0, 100);
could be a help for you.
the analogue input voltage is the scaled 0-100 then you can work with that

Serial output of ascii string giving higher voltage for more binary zeroes

I'm controlling a motor bridge via a serial port by using the voltage from the pins on the serial plug directly.
This would normally only give me the RTS and DTR pins to use (controllable through PySerial) as motor controls; however, if I send a string through the data out pin, I can generate enough voltage to control the motor bridge.
My question is--
Why do I get a higher voltage for characters with more binary zeroes in them?
A string of "~" (01111110)gets me only 1.3 volts, 'Z' (01011010) gets about 2 volts, and "#" (01000000)clears the 3 volt threshold I need operate the motor bridge.
It's not really a problem, but I feel I'm missing something conceptually important here as I assumed it would be the opposite (more binary ones = higher voltage).
Thanks in advance.
Hans Passant had the right answer: inverted outputs on RS-232. I'm just putting it so this questions doesn't stay open.

Resources