Direct Port Analog Read/Write

I'm working on a project to create a streamlined method for PC-Arduino communication. I'm using a Mega 2560 v3.

To steramline and speed up the communication, I'm using direct port modification. That way, I only have to send 1 byte to simultaneously control 8 outputs.

However, I'm not sure how this works with analog I/O. I notice the analog inputs are single bits on the F and K ports, which would imply they only have an on or and off state. Is there another register where the full 10-bit ADC data is located?

The same goes for the PWM outputs, which are 8-bit from what I understand.

Well analog pins can be used as either analog input pins or as digital input/output pins. Given that what is your question? If is it 'can I read or write 8 bit values from the analog port(s) using single port commands', the answer is yes. If however is it can I read 8 analog input values in a single port read, the answer is no, there is only a single ADC module and a multiplexer in front of it so you always first have to set the multiplexer first to select the pin to attach to the ADC and then start the ADC conversion cycle. There is a two byte ADC result register to hold the 10bit conversion result.

I don't understand how direct port manipulation can speed up Arduino-PC comms compared with using the regular Serial comms?

With Serial comms the USART does all the hard work.

...R

retrolefty:
Well analog pins can be used as either analog input pins or.......

Very informative, thanks! I was not aware of the multiplexed analog inputs. In that case, it might be worth it to just use the AnalogRead() function. I Figured all analog inputs would not be accessible within the same register.

What do you know about the PWM outputs? I understand the PWM frequency is also used in the tone generator, right? This would imply that either each PWM output runs independently, or there is a multiplexed operation that "sets" PWM values one at a time.

Robin2:
I don't understand how direct port manipulation can speed up Arduino-PC comms compared with using the regular Serial comms?

The main reason I am using direct port access is because it is accessed in full. Let me show you:

With the easy method, the setup looks like this:

 Computer to Arduino:
Set Pin 1 ON        (3 Bytes via serial)
Set Pin 2 OFF      (3 Bytes via serial)
Set Pin 3 ON       (3 Bytes via serial)
Set Pin 4 ON       (3 Bytes via serial)
Set Pin 5 ON       (3 Bytes via serial)
Set Pin 6 OFF      (3 Bytes via serial)
Set Pin 7 ON        (3 Bytes via serial)
Set Pin 8 ON       (3 Bytes via serial)

(24 Bytes in total)

Arduino:
Set Pin 1 ON       
THEN Set Pin 2 OFF    
THEN Set Pin 3 ON      
THEN Set Pin 4 ON       
THEN Set Pin 5 ON     
THEN Set Pin 6 OFF    
THEN Set Pin 7 ON        
THEN Set Pin 8 ON     

(Done in sequence, each one taking several cycles)

Now here is how it looks according to the method I'll be using.

Computer to Arduino:
Set these pins: 11111111
To these values:10111011

Total: 3 Bytes.     Command-Mask-Values

Arduino:

Set pins like this: 10111011
(Done simultaneously)

These are obviously hypothetical examples. On the mega, the pins 1-8 occur on about 3 different registers.

But notice how much smaller the port method is. In fact, I was thinking of making unmasked write commands what would only use 2 bytes. The purpose of the mask byte is to filter out which pins I want to change and which ones I want to leave.

Some of this would almost be nice to do in Assembly.

Basically, I'm trying to give the Host computer the fastest low-level access I can. So that the software abstraction can tightly sync directly with the devices.

I don't understand what you mean by the "3 Bytes via serial".

Set Pin 1 ON (3 Bytes via serial)

There is nothing to stop you sending a single byte (such as 10111011) over the serial connection and using it to update 8 pins on the Arduino all at once.

I wonder if you have your terminology a little confused.

Direct port manipulation on the Arduino is much much faster than a series of digitalWrite()s. But that has nothing to do with the process of communication between the PC and the Arduino. Obviously you will want to send the data in a style that is convenient for the Arduino to process quickly.

In any case, how do you plan to send data from your PC to the Arduino without using the USB connection and using Serial? I don't know of any other way physically to connect them to each other.

...R

ethernet shield, bluetooth shield?

Jonathanese:
To steramline and speed up the communication, I'm using direct port modification. That way, I only have to send 1 byte to simultaneously control 8 outputs.

You are confusing the communication protocol with the mechanism used to perform I/O. Since the I/O port access is massively faster than the PC comms, the performance of the I/O is essentially irrelevant. If you want to use an efficient communication protocol, go ahead. I suggest you avoid tying that protocol into details of the I/O port layout though since it won't give you any performance improvements and would make your communications protocol board-specific. Usually, one of the goals of a good protocol design is to insulate each end point end from implementation details of the other end.

I suppose what I meant to say was that it makes a lot of things easier to shrink.

I can send 10010100 over serial, then loop it through a bunch of divisions by two or something to go to a bunch of digital writes, which I hear use hundreds of cycles each. OR I can just send 10010100 over serial, then stick this byte directly into the port all at once. And again, it's simultaneous across that particular port.

I'm also not sure where I implied that I WASN'T using serial via USB, but that's what I'm using. I'm hoping to make an interface that I can use in other software. So much so that I wouldn't really need to reprogram the Arduino, but instead issue commands directly from whatever computer software I write. Perhaps a simple DLL I include which adds a class which includes several arduino models, as well as most of the commands available to them, at a speed that reduces bottlenecks in the arduino's processing time or in serial's limited baud rate.

If anything, it's more of a practice in coding an optimization I hope to be able to use in my future careers, but also a way to streamline the process of using the arduino as a USB device.

Jonathanese:
If anything, it's more of a practice in coding an optimization

By making your communication protocol specific to the port layout of a given board, you're losing the benefit of abstraction and independence from a given board's hardware layout. There are good reasons for using the Arduino API to perform I/O rather than hitting the hardware ports directly. The benefits of abstracting away details of the boards hardware layout are even more important when you're writing code that runs on a different platform. The performance concerns which you're using to justify this optimisation are not actually valid. The digital I/O is hundreds of times faster than the serial comms. If you're doing this optimisation with the idea that it will be something that will stand you in good stead during your career, I suggest you spend some time thinking about why people bother with hardware abstraction layers and platform neutral APIs and understand why it is beneficial to get away from hardware details, rather than letting dependencies on the hardware seep through your solution.

Jonathanese:
I’m also not sure where I implied that I WASN’T using serial via USB,

These were what confused me …

To steramline and speed up the communication, I’m using direct port modification.

Computer to Arduino:
Set Pin 1 ON (3 Bytes via serial)

…R