[Solved] Need help with SPI arduino Pro Micro

Hi there. I used this code here to make two arduinos communicate with each other. Arduino as SPI slave - #2 by nickgammon. Unfortunately, the code doesn't work and I really tried to solve it but I don't have a lot of XP with Arduino. Can somebody please help me with this?

I use two arduino Pro Micros. Also I connected MISO>MISO, MOSI>MOSI, SCK>SCK and SS>SS (pin 10 on Micro Pro) and GNDs and Vccs are connected to each other respectively.

Thank you.!

Are you using the exact code, with absolutely no changes?

No one of them is a slave so MISO to MOSI, MOSI to MISO.

I even tried the code with that, still no results.

Yes. I used the exact code. I even tried modifying it a little bit, still nothing.

Please post your exact and complete code in code tags.
Also, how are you powering the second board?

What results are you getting when you say no results?

Which one is the slave?

Did you test that all those wires are good?

Complete code:
**

  1. Master:

**
#include <SPI.h>
#include "pins_arduino.h"

 void setup (void)
 {
// Put SCK, MOSI, SS pins into output mode
// also put SCK, MOSI into LOW state, and SS into HIGH state.
// Then put SPI hardware into Master mode and turn SPI on
SPI.begin ();
SPI.setClockDivider(SPI_CLOCK_DIV8);

}  // end of setup

void loop (void)
{
  
char c;

// enable Slave Select
digitalWrite(SS, LOW);    // SS is pin 10

// send test string
for (const char * p = "Hello, world!\n" ; c = *p; p++)
SPI.transfer (c);

// disable Slave Select
digitalWrite(SS, HIGH);

delay (1000);  // 1 seconds delay 
}  // end of loop`

**

    • Slave:

**
#include "pins_arduino.h"

char buf [100];
volatile byte pos;
volatile boolean process_it;

void setup (void)
{
  Serial.begin (9600);   // debugging

  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);

  // turn on SPI in slave mode
  SPCR |= _BV(SPE);

  // turn on interrupts
  SPCR |= _BV(SPIE);

  pos = 0;
  process_it = false;
}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR;

  // add to buffer if room
  if (pos < sizeof buf)
      {
    buf [pos++] = c;

 // example: newline means time to process buffer
    if (c == '\n')
      process_it = true;
  
  }  // end of room available
}

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  Serial.println(process_it);
  if (process_it)
    {
    buf [pos] = 0;  
    Serial.println (buf);
    pos = 0;
    process_it = false;
    }  // end of flag set

}  // end of loop

I connect both Arduinos to my Laptop though the USB port (the one on the left is not connected in this picture but typically I do connect both of them.) I corrected the initial picture. Sorry for misinformation. BTW, apologies I couldn't include the "includes" in my tags.

This code is suppose to print Hello World! by the slave arduino in the serial monitor. I get nothing. After debugging (Serial.println(process_it); ) I found out that the flag that should be switched in the interrupt section will never be turned into TRUE.

The one on the left is slave, but since I connect both of the to the USB port, they will be identical regarding the wirings.
I don't know how to test the wires. You mean with oscilloscope?

Are you sure Serial Monitor is connected to the slave's com port?

Just with a multimeter on continuity/resistance mode.

Yeah I checked for both the slave and Master. Nothing's there.

I checked the ports with oscilloscope and found out that Sclock and SS ports have no voltages, but the MOSI port works (4.8 Volts). I also checked with a Multimeter, got the same results.

Replace the wires!

I changed the wires. The Sclock port shows zero and the SS port shows 0-20mV (it has fluctuations). By the way, the light on the RX LED of the arduino pro micro blinks which apparently means it is sending data to the slave, that is probably why I have voltage on MOSI.

One more note, I use pin 10 as SS.

Update: I figured out by changing the SS in the master code to 10 the SS pin reads the voltage high and low.

Example: digitalWrite(10, LOW);

That's an improvement, but without that clock signal, the slave cannot receive anything from the master. Disconnect the slave and use the scope to check you can see signals on both MOSI and SCK on the master's pins. If not, perhaps you have a faulty board. Depending on your scope, you may need to reduce the SPI clock speed. At SPI_CLOCK_DIV8, the signal will be 2MHz.

[Solved]: Using Oscilloscope and the device's datasheet, I found out that pin 10 on the Pro Micro is not SS/CS, but rather the RX LED is supposed to be the CS. I manually contacted a wire from ground (low) to the RX LED and got the promised (Hello World!) from the code.

Also, the original code needs a {} for the loop function to operate. Thank you guys for helping me. Cheers.

1 Like

Ah, yes, you are correct. On Pro Micro, SS is pin 8, which is not broken out, but is used for one of the on-board LEDs. I did not know this. I guess the best answer is not to plan to use Pro Micro as an SPI slave.

Great, but this does not explain why you were unable to detect the clock signal from the master with your oscilloscope. That should have been detectable even before you added the wire to the slave. The fact that the slave can receive the message means the clock signal must be working ok.

If you use the Auto-Format function in the IDE to fix the indentation in your code, it will make finding such errors much easier.

1 Like

Yeah I had changed the code for debugging, resulting in changing the SCK pin recognition. When I returned to the original code, that issue was resolved.

Thank you Paul. :facepunch:

That doesn't make any sense to me, but glad you got it working. :grinning: