USART on UNO MISO held high?

Hi,

I've been followng Nick Gammon's example #3 to implement USART on a genuine UNO. I am communicating with an AD7689.

I can send bytes correctly but cannot seem to read back responses.

I have found that the MISO line stays HIGH before and after transfers, could that be the issue?

See attached scope screen shots

Any thoughts would be a great help!
Cheers,
Bob

Is the MISO pin the Rx pin? If so, the usb-serial chip may be the cause.

And why can't you use the normal hardware SPI?

Hi !

Thanks for your help.

Indeed the MISO pin is the RX pin. If the usb-serial chip is the culprit, is there any way to fix it so I can use the rx without interference?

I am experimenting with USART so as to have several independent SPI busses in view of using an ATmega 2650 in the future.

First I am practicing on the UNO, though...

Has anyone ever used Nick Gammon's USART code and have a working example of 2 way communication?

The MISO isn't controlled by the Arduino at all, it's just read. And a SPI device let's MISO float when Chip Select is not active. In that case the Tx of the Serial-USB will pull it high. But then the Arduino will not read it so no problem.

As far as the problem, did you set the correct Data Order, Clock Phase, Clock Polarity (according to Nick's notes register UCSR0C)?

And just on a note, SPI is a bus, so unless you have explicit need to have two buses there is no need to use two. You can just add multiple SPI devices to the same bus. All you need is an extra pin for the CS of the new device.

septillion:
As far as the problem, did you set the correct Data Order, Clock Phase, Clock Polarity (according to Nick's notes register UCSR0C)?

I couldn't understand how to set those values from NG's examples.

I copied his settings:

UCSR0C = _BV (UMSEL00) | _BV (UMSEL01);  // Master SPI mode

But I would like to set MSB first, and SPI MODE 0 as well.

Would you know how to do it?

Then you'll have to open up the datasheet to see how to set the register :slight_smile:

But do you really need two SPI buses?

Yes, In fact I need 4 SPI buses, but that will be done on the ATMega 2560 with all pins broken out.

I am waiting to receive my full breakout, that's why I'm experimenting with the UNO.

I did look into the datasheet, but my understanding is not good enough to follow the instructions there for setting up USART. I will continue to study it but I would really appreciate any help that anyone could give!

Thanks!
Bob

Why do you need 4 SPI buses? :o

In the datasheet you need to look for register UCSR0C. Now you set bit UMSEL00 (bit 6) and bit UMSEL01 (bit 7) of that register which is master SPI. bit UCPOL0 and UCPOH0 set the SPI mode. But leaving them unset (like now) is SPI mode 0. See page 19 of the datasheet.

I need to use theHW SPI for slave mode, and the others in master mode to read various devices. The PCB tracks are like that...

It seems to me that my settings are good for MSB first and and writing on leading edge and reading on trailing edge, But I must be mistaken because it continues to fail.

Thanks so much for your help!

I have found that the MISO line stays HIGH before and after transfers, could that be the issue?

You mean the UART RxD pin, right? It shouldn't matter. The uno essentially has a pull-up resistor on that line as part of the circuitry used for Async Serial communications (Serial.xxx, and sketch upload), but an SPI slave would actually drive those pins and override the Async circuitry.... (unless the high signal interferes with the slave's ability to detect that it can send data...)

gratefulfrog:
I need to use theHW SPI for slave mode

Fair enough :slight_smile:

gratefulfrog:
and the others in master mode to read various devices.

Why can't they be on a single bus?

gratefulfrog:
The PCB tracks are like that...

Yeahhh, never make a PCB before prototyping ::slight_smile:

gratefulfrog:
It seems to me that my settings are good for MSB first and and writing on leading edge and reading on trailing edge,

I do hate the terms leading and trailing here :s Because it depends on the phase if that's rising or falling.

But now, in mode 0, it's sampling on the rising (leading) and clock at rest LOW.

Bit UDORD0 (bit 2) is the data order and cleared is MSB first.

Registers UBRR0 are the speed, value 3 is 2MHz @ 16MHz clock.

Seems all fine. Have you tried to connect the same device to the normal SPI with the same settings (MSB first, spi mode 0, 2MHz)?

Hi!

Thanks again for all this support.

I have perfect comms using the HW SPI library. I use the exact same code, substituting calls to encapsulated versions of NG's code for the various HW calls.

My HW SPISettings call is:

SPISettings(16000000,MSBFIRST,SPI_MODE0 )

And my USART setup call is:

    pinMode (MSPIM_SS, OUTPUT);   // SS
  
    // must be zero before enabling the transmitter
    UBRR0 = 0;
  
    UCSR0A = _BV (TXC0);  // any old transmit now complete
    
    pinMode (MSPIM_SCK, OUTPUT);   // set XCK pin as output to enable master mode
  
    UCSR0C = _BV (UMSEL00) | _BV (UMSEL01);  // Master SPI mode
    UCSR0B = _BV (TXEN0) | _BV (RXEN0);         // transmit enable and receive enable
    
    // must be done last, see page 206
    UBRR0 = 0; // full speed //3 // 2 Mhz clock rate

The MOSI signals are the same, but the replies are not. I cannot understand why.

I use the same code, so the same delayMicroseconds calls are made to ensure that there is enough time.

I am at a loss, but thank you so much for your help!

gratefulfrog:
The MOSI signals are the same, but the replies are not. I cannot understand why.

The Arduino only makes the SCK and MOSI, MISO is made by the device. So if they are not the same it's caused by the device. Only other thing I can think of is that the drive monitored the MISO line and that's causing trouble because it's pulled high. If it's a real Arduino you can try to put the ATmega16U (the chip that does the USB-Serial) in reset. This should release the Rx pin and make it float as well.

septillion:
If it's a real Arduino you can try to put the ATmega16U (the chip that does the USB-Serial) in reset.

It is a real arduino, but how does one do that? I searched on the web, but found no instructions that I could understand. I am sorry for my ignorance....

The ATmega16U has it's own ISP header called ICSP1, it's the one near the USB. It has the reset of the ATmega16U on it on pin 5. Just connect that to pin 5 (which is GND) to keep the ATmega16U in reset. If I'm correct that are the two pins closest to the USB socket.

septillion:
If I'm correct that are the two pins closest to the USB socket.

You are indeed correct, and by shorting those pins, i.e. pins 5 & 6 of the ICSP header (those facing the USB connector), the USART comms now work PERFECTLY!!!

I don't know how to express my gratitude for your perseverance and great energy to help me!!!

Here's a link to the code.

And here's a link to the video showing it working!

Thanks so much,
Bob

Great to hear it works! No idea what it does though :stuck_out_tongue:

Very quick scan:
For the heartbeat, no need to save state, you can just read it. That's why I like to add the following function to most of my projects.

inline void digitalToggle(uint8_t pin){
  digitalWrite(pin, !digitalRead(pin));
}

And don't know what you all try to do, but you're using a lot of delay()... And that is a source of a lot of headaches. Letting the loop() loop is better most of the time.

Especially because you say you need 3 SPI master buses would expect speed to be an issue. Otherwise you could connect all devices just to a single bus :wink:

Nice trick for the heart beat!

This code is only designed to get the USART comms operational. There is no "real" code here, except for the yspi and ad7689 libraries. All those delays are to give me time to set the trigger on my oscilloscope to capture a particular communication frame.

Now that we have a working USART implementation on the UNO we will port it to our ATmega2650 based custom boards.

As an aside, we had originally planned to do this debugging on an Arduino Mega, but were sad to discover that 16 of the microprocessor pins are NOT CONNECTED on the Arduino Mega. And sadly, the USART CLK pins are among those 16...

In any event, it has been great to get USART working 100% even if it is on the UNO.

Next we will port this code to our custom boards and/or do more debugging on an ITEAD Iteaduino mega derivative which does have all 100 of the microprocessor pins connected, if it ever arrives in the post :wink:

:slight_smile: Then still one question in my head, why can't the devices share the SPI?

septillion:
:slight_smile: Then still one question in my head, why can't the devices share the SPI?

Seeing as I'm only a programmer, I asked the electronics designer your question.

Here's the reply I got from him:

Speed is the key: when 2 or more devices share the same bus, only one device can use it at a time. Putting them all on a different bus, with a different clock generator (as configured in the USARTs individually) allows all to be addressed simultaneously. When communication with one ADC is initiated, the MCU can directly move on to the next one and initiate communication there as well, and so on. Once a cycle is complete, the respective RX interrupt flags will be set, and the MCU can read out data from the receive registers.
In summary, putting them all on the same bus forces sequential operation, while putting them on different buses enables the opportunity of parallelization.