Problema con la comunicación SPI entre Arduino/Atmega328P y Raspberry Pi

Tengo un chip Atmega328P (que se usa como Arduino) que me gustaría conectar a una Raspberry Pi a través de SPI.

Originalmente tenía un Atmega328P funcionando a 3,3 V usando su propio cristal interno de 8 MHz en lugar de un cristal externo de 16 MHz. El Atmega fue alimentado desde el pin de 3.3v de la Raspberry Pi. Pude conectar directamente los pines MISO/MOSI/SCLK/CE0 entre los dos dispositivos y usé con éxito el Pi como maestro SPI y el Atmega como esclavo SPI.

Ahora quiero usar un Atmega328 a 5V alimentado desde CC externa (LM317, etc.) usando un cristal externo de 16MHz. Obviamente, los pines Atmega de 5 V no pueden comunicarse con los pines Pi de 3,3 V, así que obtuve un convertidor de nivel lógico bidireccional ( https://www.sparkfun.com/products/12009 ). Este es mi esquema actual:

Esquemático

Mi código SPI ya no funciona y no estoy muy seguro de por qué. ¿Es esta la forma correcta de conectar 5V Atmega y 3.3V Pi para comunicación SPI? ¿Me estoy perdiendo alguna conexión?

ACTUALIZACIÓN : terminé probando la comunicación I2C y funcionó de inmediato, así que creo que voy a cambiar a eso. Solo necesitaba comunicación de baja velocidad entre Atmega y Pi, por lo que se adapta a mis necesidades. Algún día tendré que probar algunas de las sugerencias a continuación.

Esta pregunta solo puede resolverse aceptando una respuesta. Entonces, publique en el formulario de respuesta que ha cambiado a I2C como solución, o acepte la respuesta explicando los problemas de velocidad involucrados en el uso de un traductor destinado a I2C para I2C, si cree que es un resumen más útil de la situación.

Respuestas (2)

El problema con los convertidores de nivel como ese es que solo pueden ir tan rápido. Intente reducir la velocidad de su SPI.

Si tiene un alcance, verifique los niveles de las señales para asegurarse de que sean lo suficientemente altos, especialmente la línea del reloj, en ambos lados.

Los convertidores de nivel agregan mucha capacitancia en el bus. Estoy de acuerdo con reducir la velocidad y verificar los niveles en un alcance.
@Annie: en este caso, no es realmente la capacitancia. Es que estos convertidores solo conducen alto a través de resistencias pull-up que por defecto son 10K. Agregar resistencias pull-up externas de valor más pequeño aumentaría la capacidad de velocidad, o mejor ir a un chip que pueda controlar activamente ambas polaridades Aquí no se necesita un convertidor bidireccional, las líneas SPI son unidireccionales en uso común.
Ambos tienen razón. La capacitancia adicional combinada con pullups débiles limita la velocidad. @ChrisStratton Buen punto sobre las resistencias pull-up externas, eso podría funcionar.
Los problemas de velocidad de RC involucran tanto la resistencia como la capacitancia, por supuesto. Pero aunque la capacitancia aumenta, aún permanece en los picofaradios. Por el contrario, el uso de uno de estos aumenta la parte de la resistencia del problema en la dirección del flanco ascendente en muchos órdenes de magnitud en comparación con los propios controladores del chip. La dirección del borde descendente ve la capacitancia, por supuesto, pero no sufre tanta resistencia añadida, y una verificación con un alcance mostrará que el problema son los bordes ascendentes, no los descendentes.
@ChrisStratton Eso tiene mucho sentido. Debo admitir que no sé cuál es la resistencia pull-up para Raspberry Pi o ATMEGA328P. ¿Muchos órdenes de magnitud menos? ...tal vez
Cuando impulsan las salidas, esos chips normalmente las impulsan activamente tanto a niveles altos como bajos. En realidad, no tienen una resistencia de "arranque" en el sentido habitual del término, aunque, por supuesto, tienen una fuente de impedancia. Por el contrario, estos convertidores solo conducen bajo.
@ChrisStratton Tenía la suposición errónea de que esos pines eran de colector abierto todo el tiempo, no solo cuando se usaban como GPIO. Gracias por los comentarios.
En realidad es al revés. Son principalmente solo drenaje abierto basado en hardware cuando se usan en un modo de función especial como I2C. Si mal no recuerdo, cuando se usan como GPIO, ambos chips mencionados en la pregunta deben tener un comportamiento de drenaje abierto emulado en el software, ya sea haciendo que el pin sea una salida baja o una entrada. En contraste, muchas MCU más típicas en realidad tienen un modo GPIO de drenaje abierto.
@ChrisStratton Una mirada a la hoja de datos del ATMEGA328P verifica exactamente lo que está diciendo. ¡Aprendí algo nuevo! Gracias de nuevo.
Lo siento, soy bastante nuevo en todo esto. De los comentarios anteriores, ¿debería intentar agregar algunas resistencias o simplemente usar la función pinMode () de Arduino? Intentaré agregar mi código Arduino a la pregunta este fin de semana.
@darkadept Estábamos discutiendo detalles sobre los aspectos de hardware de los pines. Puede agregar resistencias pull-up externas, las integradas serán demasiado débiles, suponiendo que incluso pueda habilitarlas mientras usa el puerto para SPI. Todavía recomendaría reducir la velocidad de su SPI.
@ChrisStratton Sí, tienes razón, la alta resistencia es un factor mucho más importante.

Los condensadores C1 y C2 alrededor de su cristal son demasiado grandes y es probable que interfieran con su reloj. Consulte la hoja de datos de ATmega, deberían ser aproximadamente 22pF.