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
*********************************************************************************************************/
Спасибо
@Ross Hanna, 👍1
Обсуждение0
- Как вывести истинное аналоговое напряжение на выходной контакт
- Как именно работает двойной выход 5В и 3,3В на Uno R3?
- Пытаюсь прошить ESP8266 с помощью Arduino UNO
- Диапазон выходного напряжения от 0 до 5 В
- Сдвиг уровня 5В <-> 3,3В
- Можно ли сделать FastLED быстрее?
- Правильный выбор источника питания для Arduino - ESP8266 - HC-SR04
- Сколько напряжения и ампер для 2 сервоприводов SG90?
поиск * преобразователь логического уровня arduino*, @Jaromanda X
Это мой план на то время, когда я вернусь, но я хотел протестировать установку перед отъездом. Нет ли быстрых исправлений, чтобы я мог протестировать в течение 10 секунд?, @Ross Hanna
Почему делитель напряжения должен использоваться только для медленных сигналов? Действительно ли паразитная емкость линий настолько велика?, @chrisl
MCP2515 отлично работает при напряжении 3,3 В. Проверьте электрические характеристики в техническом описании: "VDD: от 2,7 В до 5,5 В"., @Majenko
Спасибо majenko, продавец, у которого я его купил, отключил его только на 5 В, так что, должно быть, допустил ошибку. Вопрос с делителем напряжения, в котором я не уверен. По-видимому, существует много противоречивых мнений о методах снижения напряжения для датчиков. Я где-то читал, что такие вещи, как spi-делители напряжения, недостаточно быстры, @Ross Hanna