5 В MCP2515 в 3.3V Teensy. Как уменьшить напряжение MISO

Поэтому, чтобы попытаться ускорить свой проект, я перешел от использования двух UNO к UNO на стороне получателя и teensy 3.6 на стороне отправителя. Однако никаких кубиков. UNO не получает никаких данных и даже не пытается их распечатать. Я обнаружил, что это доходит до линии;

if(!digitalRead(CAN0_INT))

и тогда программа не будет продолжена. Я заменил teensy и снова запустил тот же код на UNO на отправителе, чтобы проверить, все ли соединения работают, и все в порядке, как только я подключаю teensy, сообщения не поступают.

Насколько я могу судить, модуль MCP2515 не работает на 3,3 В, поэтому мне интересно, так ли это. Итак, мой план состоит в том, чтобы запитать MCP2515 от источника 5 В и понизить напряжение на линии прерывания и МИСО до 3,3 В, чтобы крошка была в безопасности.

Однако я не уверен, как это сделать, и мне также нужно быстрое решение, поскольку сегодня днем я уезжаю до января, и у меня нет под рукой логического преобразователя. Я видел, что вы можете использовать делитель напряжения для снижения напряжения, но будет ли это проблемой, поскольку это решение, по-видимому, предназначено только для медленных сигналов?

Любые другие мысли о том, почему эта настройка не будет работать, приветствуются. Так что просто предположим, что я добавил свой код, который работает на UNO, но не на teensy. Моя единственная другая мысль, почему это не сработает, заключается в том, что в teensy 3.6 уже есть CAN-шина, и код несовместим?

Отправитель

// МОГУ прислать пример
//

#include <mcp_can.h>
#include <SPI.h>
#include <Wire.h>

const int MPU_addr = 0x68; // I2C-адрес MPU-6050

float lastTimeSent;
const float intervalSendMs = 0.000001; // Период отправки в миллисекундах
float currMillis;

int16_t AccX, AccY, AccZ, Tmp, GyX, GyY, GyZ; 
uint8_t dataArray[32];
uint8_t data1[8], data2[8];
int Switch = 7;
const int AS_Pin = 10;

#define CAN0_INT 2    // Установить значение INT на вывод 2
MCP_CAN CAN0(9);     // Установить CS на вывод 10

void setup()
{
    Serial.begin(115200);

    initializeMCP2515();

    pinMode(Switch, OUTPUT);
    digitalWrite(Switch, HIGH);

    initializeMPU9250();

}

void loop()
{
    currMillis = millis();

    if ((currMillis - lastTimeSent) >= intervalSendMs)
    {
        lastTimeSent += intervalSendMs;

        readFromMPU9250();

        //MPU_Data_to_CAN_Array();

        convertDataToPackets();

        // Отправить два кадра; если первая отправка прошла успешно, отправьте также второй, в противном случае прервите
        // отправить кадр данных 1: ID = 0x100, стандартный кадр CAN, длина данных = 8 байт, 'data' = массив байтов данных для отправки
        // отправить кадр данных 2: ID = 0x101, стандартный кадр CAN, длина данных = 8 байт, 'data' = массив байтов данных для отправки
        if (CAN0.sendMsgBuf(0x100, 0, 8, data1) == CAN_OK)
            CAN0.sendMsgBuf(0x101, 0, 8, data2);
    }

                  Serial.print(currMillis);
                  Serial.print("\t");
                  Serial.print(AccX);
                  Serial.print("\t");
                  Serial.print(AccY);
                  Serial.print("\t");
                  Serial.print(AccZ);
                  Serial.print("\t");
                  Serial.print(GyX);
                  Serial.print("\t");
                  Serial.print(GyY);
                  Serial.print("\t");
                  Serial.println(GyZ);


}

//===================================================================================
// ФУНКЦИИ                                             
//===================================================================================
void initializeMCP2515()
{
    // Инициализируйте MCP2515, работающий на частоте 16 МГц со скоростью передачи данных 500 КБ / с, а маски и фильтры отключены.
    if(CAN0.begin(MCP_ANY, CAN_1000KBPS, MCP_16MHZ) == CAN_OK)
        Serial.println("MCP2515 Initialized Successfully!");
    else
        Serial.println("Error Initializing MCP2515...");

    CAN0.setMode(MCP_NORMAL);   // Переключиться в обычный режим, чтобы разрешить передачу сообщений
}

void initializeMPU9250()
{
  pinMode(AS_Pin, OUTPUT);
  digitalWrite(AS_Pin, HIGH);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.setDataMode(SPI_MODE0);
  SPI.begin();
}

void readFromMPU9250()
{
      digitalWrite(AS_Pin, LOW); 
  SPI.transfer(0x80|0x3B);

  for(int i = 0; i < 14; i++){
  dataArray[i] = SPI.transfer(0);
  }
  digitalWrite(AS_Pin, HIGH);
delay(50);

AccX = dataArray[0]<<8|dataArray[1];
AccY = dataArray[2]<<8|dataArray[3];
AccZ = dataArray[4]<<8|dataArray[5];
GyX = dataArray[8]<<8|dataArray[9];
GyY = dataArray[10]<<8|dataArray[11];
GyZ = dataArray[12]<<8|dataArray[13];
}

void convertDataToPackets()
{
    long2Byte(currMillis, 0, data1);
    int2Byte(AccX, 4, data1);
    int2Byte(AccY, 6, data1);

    int2Byte(AccZ, 0, data2);
    int2Byte(GyX, 2, data2);
    int2Byte(GyY, 4, data2);
    int2Byte(GyZ, 6, data2);
}

void int2Byte(int16_t input, int pos, uint8_t *data)
{
    for (int i = 0; i < 2; i++)
    {
        data[i + pos] = ((input >> (i * 8)) & 0xff);
    }
}

void long2Byte(uint32_t input, int pos, uint8_t *data)
{
    for (int i = 0; i < 4; i++)
    {
        data[i + pos] = ((input >> (i * 8)) & 0xff);
    }
}

/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

Приемник

// CAN Receive Example
//

#include <mcp_can.h>
#include <SPI.h>

long unsigned int rxId;
unsigned char len = 0;
unsigned char rxBuf[8];
uint8_t receivedFirstFrame;

char msgString[128];                        // Array to store serial string
uint32_t TimeMicro;
int16_t AccX, AccY, AccZ, GyX, GyY, GyZ;

#define CAN0_INT 2  // Set INT to pin 2
MCP_CAN CAN0(10);   // Set CS to pin 10


void setup()
{
    Serial.begin(115200);

    initializeMCP2515();

    Serial.println("MCP2515 Library Receive Example...");
    Serial.println("waiting for data");
    receivedFirstFrame = 0;
    Serial.println("data recived?");
}

void loop()
{
    if(!digitalRead(CAN0_INT))
    {
        // Received a message
        if (CAN0.readMsgBuf(&rxId, &len, rxBuf) == CAN_OK)
        {
            // Note: the above line is not like in the examples, but looking at the code the
            // function may return if no message was in the queue, so I think this is safer

            // Let's check if it is one of the known messages
            switch (rxId)
            {
            case 0x100:
                { // Received first frame
                    // Decode the content and store that the first frame was received
                    decodeFirstFrame(rxBuf);
                    receivedFirstFrame = 1;
                    Serial.print(TimeMicro);
                    Serial.print("\t");
                    Serial.print(AccX);
                    Serial.print("\t");
                    Serial.print(AccY);

                }
                break;
            case 0x101:
                if (receivedFirstFrame)
                { // Received second frame after a first frame
                    // Decode the content
                    decodeSecondFrame(rxBuf);

                  Serial.print("\t");
                  Serial.print(AccZ);
                  Serial.print("\t");
                  Serial.print(GyX);
                  Serial.print("\t");
                  Serial.print(GyY);
                  Serial.print("\t");
                  Serial.println(GyZ);

                    //printDataToSerial();

                    receivedFirstFrame = 0;
                }
                break;
            }
        }
    }

    TimeMicro = 0;
    AccX = 0;
    AccY = 0;
    AccZ = 0;
    GyX = 0;
    GyY = 0;
    GyZ = 0;
}

//===================================================================================
//                                  FUNCTIONS                                             
//===================================================================================

void initializeMCP2515()
{
    // Initialize MCP2515 running at 16MHz with a baudrate of 500kb/s and the masks and filters disabled.
    if(CAN0.begin(MCP_ANY, CAN_1000KBPS, MCP_16MHZ) == CAN_OK)
        Serial.println("MCP2515 Initialized Successfully!");
    else
        Serial.println("Error Initializing MCP2515...");

    CAN0.setMode(MCP_NORMAL);   // Change to normal mode to allow messages to be transmitted

    pinMode(CAN0_INT, INPUT);                            // Configuring pin for /INT input
}

void decodeFirstFrame(uint8_t *rxBuff)
{
    TimeMicro = byte2Double(TimeMicro, 0, rxBuff);
    AccX = byte2Int(AccX, 4, rxBuff);
    AccY = byte2Int(AccY, 6, rxBuff);
}

void decodeSecondFrame(uint8_t *rxBuff)
{
    AccZ = byte2Int(AccZ, 0, rxBuff);
    GyX = byte2Int(GyX, 2, rxBuff);
    GyY = byte2Int(GyY, 4, rxBuff);
    GyZ = byte2Int(GyZ, 6, rxBuff);
}


uint32_t byte2Double(uint32_t output, int pos, uint8_t data[4]){
      for (int i = 0; i < 4; i++)
    {
      output += ((uint32_t)data[i + pos]) << (i * 8);
    }
    return output;
}

int16_t byte2Int(int16_t output, int pos, uint8_t data[2]){
      for (int i = 0; i < 2; i++)
    {
      output += ((int16_t)data[i + pos]) << (i * 8);
    }
    return output;
}
/*********************************************************************************************************
  END FILE
*********************************************************************************************************/

Спасибо

, 👍1

Обсуждение

поиск * преобразователь логического уровня arduino*, @Jaromanda X

Это мой план на то время, когда я вернусь, но я хотел протестировать установку перед отъездом. Нет ли быстрых исправлений, чтобы я мог протестировать в течение 10 секунд?, @Ross Hanna

Почему делитель напряжения должен использоваться только для медленных сигналов? Действительно ли паразитная емкость линий настолько велика?, @chrisl

MCP2515 отлично работает при напряжении 3,3 В. Проверьте электрические характеристики в техническом описании: "VDD: от 2,7 В до 5,5 В"., @Majenko

Спасибо majenko, продавец, у которого я его купил, отключил его только на 5 В, так что, должно быть, допустил ошибку. Вопрос с делителем напряжения, в котором я не уверен. По-видимому, существует много противоречивых мнений о методах снижения напряжения для датчиков. Я где-то читал, что такие вещи, как spi-делители напряжения, недостаточно быстры, @Ross Hanna