Не работает arduino когда не подключено к ПК

Столкнулся с таким вопросом. Написал код для подключения arduino к авто. С помощью вот такого соединения и программы Serial Port Monitor проверял работоспособности и отлаживал.


Когда все подключено к ПК в Serial Port Monitor команды приходят, а если arduino не подключено к ПК, а запитано от другого источника питания ничего нет. Что я делаю не так подскажет кто или досталась бракованная плата arduino?

Не пробовали к Нано питание подключить? :slight_smile: - на фото его нет.

1 лайк

Знакомое кино.
Но сначала бы увидеть код…

1 лайк

и полную схему

1 лайк

И что Вас удивляет?

Открою Вам секрет. Если электронное устройство оставить без питания, то оно не работает (кто не ест – тот не работает)! (можете называть это Законом Петровича).

Какой? Вот этой?

Ну во-первых черным по белому написано

А дочитывать вы не пробовали?

А ТО СРАЗУ УМНИЧАЕТЕ НЕ В ТЕМУ

3 лайка

Писал что подключал. Это фото сделано оборудование которое использую чтобы понятнее было. А так все подключал к ПК (и ch341a и ардуино) и работает, а если ch341a подключен к ПК, а ардуино отключить и подать питание ничего не отправляется.

ничего не понятно.
Нарисуйте схему с указанием ВСЕХ подключений, включая питание.

А как может что-то прийти в Serial Port Monitor, если

для теста соединены ch341a и ардуино друг с другом через rx и tx. Экран по сути не важен, он для проверки работы на авто.

А как тогда работают проекты на авто без ПК?

Вы русский язык плохо понимаете?

НАРИСУЙТЕ

ПОЛНУЮ

схему

ВКЛЮЧАЯ ПИТАНИЕ

1 лайк

Пробовал. Эта фраза противоречит другой:

Поскольку вторая фраза подкреплена фото - ей доверия больше.

Про Ваш другой источник возникает очевидный вопрос: “а земля у него соединена с землёй компьютера”? Но это было бы видно из схемы или фото, на котором этот источник бы был.

Не пробовали нормально нарисовать схему, привести актуальное фото и толково объяснять проблему и схему, вместо того, чтобы мозг выносить?

Если бы Вы знали, что важно, а что - нет, этой темы на форуме не было бы.

Или рисуйте полную схему, приводите полный скетч и и прикладывайте информативное фото, или решайте свои проблемы самостоятельно.

Пятница началась удачно!

второе

1 лайк

Вот код

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#include <utf8rus2.h>

SoftwareSerial K_LINE(2, 3);  // RX, TX

#define TIMER_DELAY \
  Delay = 0; \
  timerdelay = curmillis  // включение этого таймера
#define TFT_CS     10
#define TFT_RST    8
#define TFT_DC     9
#define SERIAL_BAUDRATE 10400

const byte PCMaddress = 0x7A;  // адрес эбу

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // Инициализация объекта для работы с дисплеем

byte header = 0;        // состояние заголовка
byte message_size = 0;  // размер тела принимаемого сообщения, кол-во байт

byte j = 2;  // инкремент
byte n = 2;
const byte bufsize = 100;   // размер буфера принятого сообщения
byte buf[bufsize] = { 0 };  // буфер принятого сообщения
byte checksum = 0;          // контрольная сумма входящего сообщения
uint32_t curmillis = 0;     // снимок системного времени
byte delaybyte_TX = 0;      // задержка между байтами отправляемого сообщения
byte waitbyte_RX = 1;       // задержка, мс для успевания заполнения буфера RX (подрегулировать в зависимости от уровня жизнидеятельности на Марсе)
uint32_t timerdelay = 0;    // таймер ожидания байт (для успевания заполнения буфера УАРТ)
bool Delay = 0;             // таймер ожидания байт (для успевания заполнения буфера УАРТ)
#define TIMER_DELAY \
  Delay = 0; \
  timerdelay = curmillis  // включение этого таймера

uint32_t prevRESETheader = 0;  // таймер сброса заголовка если в момент приёма сообщения данные оборвались
bool RESETheader_timer = 0;    // таймер сброса заголовка если в момент приёма сообщения данные оборвались


uint32_t prevtimeRequest = 0;
uint16_t periodRequest = 1000;  // периодичность запроса параметров ЭБУ, мс
int Init = 0;
uint32_t prevInit = 0;

String VIN="";
int Speed_engine;
int Vitesse;

//**************************** команды, посылаемые на ЭБУ

byte StartSession[] = { 0x81 };       // команда на старт диагностики (может также быть 82)
byte StopSession[] = { 0x82 };        // команда на стоп диагностики
//byte DataRequest[] = { 0x21, 0x80 };  // команда на запрос параметров
byte DataRequest[] = { 0x21, 0xAA };  // команда на запрос параметров
byte VINRequest[] = { 0x21, 0x81 };  // команда на запрос параметров
//byte DataRequest[] = { 0x21, 0x01 };  // команда на запрос параметров

//****************************

void lcdPrint(int x, int y, int c1, int c2, String s, int width = 0, int f = 0){
  String ss;
  tft.setCursor(x,y);
  if (width == 0) {
    width = s.length();
  }
  while (ss.length() < width-s.length()) ss += " ";
  ss += s;
  if (c2 == 0){
    tft.setTextColor(c1);
  }
  else{
    tft.setTextColor(c1, c2);
  }
  tft.print(ss);
}

String str_buf_word(byte buf[], int n, int size){
  byte word[size] = { 0 }; // Очистка слова перед формированием
  for (int i = n; i < size; i++) {
    word[i-n] = buf[i]; 
  }
  return String((char*)word);;
}

void setup() {
  Serial.begin(SERIAL_BAUDRATE);   // настойки монитора порта отладки
  K_LINE.begin(SERIAL_BAUDRATE);  // настройки шины к-лайн
  delay(2000);
  tft.initR(INITR_BLACKTAB);     // Инициализация дисплея
  tft.fillScreen(ST7735_BLACK); // Очистка экрана перед выводом новых данных
  tft.setTextColor(ST7735_WHITE); // Установка цвета текста
  tft.setRotation(3);
  tft.setTextSize(1,2);
  lcdPrint(0, 20, ST7735_WHITE, ST77XX_RED, String("-----------------"));
  tft.setTextSize(2);
  lcdPrint(0, 0, ST7735_WHITE, ST77XX_RED, utf8rus2(" Связь с ЭБУ "));
  lcdPrint(0, 50, ST7735_WHITE, ST77XX_RED, utf8rus2("Обороты"));
  lcdPrint(0, 70, ST7735_BLACK, ST77XX_GREEN, String("------"), 6);
  lcdPrint(85, 70, ST7735_BLACK, ST77XX_GREEN, utf8rus2("об/мин"));
  lcdPrint(0, 90, ST7735_WHITE, ST77XX_RED, utf8rus2("Скорость"));
  lcdPrint(0, 110, ST7735_BLACK, ST77XX_GREEN, String("------"), 6);
  lcdPrint(85, 110, ST7735_BLACK, ST77XX_GREEN, utf8rus2("км/ч"));
}

void loop() {
  curmillis = millis();  // снимок системного времени

  K_LINEread();  // читаем шину к-лайн

  if (curmillis - prevtimeRequest > periodRequest) {  // периодически делаем запрос параметров

    if (Init) {
      lcdPrint(0, 0, ST7735_BLACK, ST77XX_GREEN, utf8rus2(" Связь с ЭБУ "));
      if (Init == 1) SendMessage(VINRequest, sizeof(VINRequest));
      else SendMessage(DataRequest, sizeof(DataRequest));
    }else SendMessage(StartSession, sizeof(StartSession));
    prevtimeRequest = curmillis;
  }

  if (curmillis - prevInit > 10000) {
    SendMessage(StopSession, sizeof(StopSession));
    lcdPrint(0, 0, ST7735_WHITE, ST77XX_RED, utf8rus2(" Связь с ЭБУ "));
    tft.setTextSize(1,2);
    lcdPrint(0, 20, ST7735_WHITE, ST77XX_RED, String("-----------------"));
    tft.setTextSize(2);
    lcdPrint(0, 110, ST7735_BLACK, ST77XX_GREEN, String("------"), 6);
    lcdPrint(0, 70, ST7735_BLACK, ST77XX_GREEN, String("------"), 6);
    Init = 0;
    prevInit = curmillis;
  }  // периодически делаем сброс инита, если ЭБУ не отвечает
}




void SendMessage(const byte *command, const size_t size) {
  const byte siZe = size + 4;
  byte Mes[siZe];
  byte Checksum = 0;
  for (byte i = 0; i < siZe; i++) {
    if (i == 0) {
      Mes[i] = size;
      bitWrite(Mes[i], 7, 1);
    }
    if (i == 1) Mes[i] = PCMaddress;
    if (i == 2) Mes[i] = 0xF1;
    if (i == 3) {
      for (byte t = 0; t < size; t++) {
        Mes[i] = command[t];
        Checksum += Mes[i];
        K_LINE.write(Mes[i]);
        //Serial.write(Mes[i]);
        i++;
      }
    }
    if (i != siZe - 1) Checksum += Mes[i];
    else Mes[i] = Checksum;
    K_LINE.write(Mes[i]);
    //Serial.write(Mes[i]);
  }
}


void K_LINEread() {
      
  if (K_LINE.available()) {
  //if (Serial.available()) {
    // первый старт байт
    if (header == 0 && Delay) {
      TIMER_DELAY;
      buf[0] = K_LINE.read();
      //buf[0] = Serial.read();
      if (!bitRead(buf[0], 6) && bitRead(buf[0], 7)) {
        header = 1;
        RESETheader_timer = 1;
        prevRESETheader = curmillis;
      }
    }

    // второй старт байт
    if (header == 1 && Delay) {
      TIMER_DELAY;
      buf[1] = K_LINE.read();
      //buf[1] = Serial.read();
      if (buf[1] == 0xF1) {
        header = 2;
      } else {
        header = 0;
        RESETheader_timer = 0;
      }
    }

    // третий старт байт
    if (header == 2 && Delay) {
      TIMER_DELAY;
      buf[2] = K_LINE.read();
      //buf[2] = Serial.read();
      if (buf[2] == PCMaddress) {
        message_size = buf[0];
        if (buf[0] != 0x80) {
          header = 4;
          message_size &= ~0x80;
          j = 3;
          n = 3;
        } else {
          header = 3;
          j = 4;
          n = 4;
        }
        if (message_size > bufsize) message_size = bufsize;
        checksum = 0;
      } else {
        header = 0;
        RESETheader_timer = 0;
      }
    }
    // если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
    if (header == 3 && Delay) {
      TIMER_DELAY;
      buf[3] = K_LINE.read();
      //buf[3] = Serial.read();
      message_size = buf[3];
      if (message_size > bufsize) message_size = bufsize;
      checksum = 0;
      header = 4;
    }
    
    // пишем тело сообщения
    if (header == 4 && Delay && j < message_size + n + 1) {
      buf[j] = K_LINE.read();
      //buf[j] = Serial.read();
      j++;
      if (j < message_size + n) checksum ++;  // подсчёт КС
      
      if (j == message_size + n) header = 5;
      TIMER_DELAY;
      
    }
  }  // end of K_LINE.available()
  // сообщение приняли, действуем
  if (header == 5) {
    checksum ++;
    TIMER_DELAY;
    Serial.print(F("Receive from PCM:     "));
    for (byte i = 0; i < message_size + n + 1; i++) {
      if (buf[i] <= 0x0F) Serial.print(F("0"));
      Serial.print(buf[i], HEX);
      Serial.print(" ");
    }  // Отладка в монитор порта
    Serial.println();
    // если контрольная сумма верна:
    if (message_size == checksum) {
      prevInit = curmillis;  // сбрасываем таймер сброса инита, если получили хоть какое-то сообщение от ЭБУ
      if (buf[n] == 0xC1) Init = 1;  // если пришёл ответ на запрос инита, делаем инит прошёл успешно
      // ниже если получили длинный ответ от ЭБУ с параметрами парсим его, я взял только температуру   ДВС
      else if (buf[n] == 0x61 && buf[n + 1] == VINRequest[1]) {
        VIN = str_buf_word(buf, n+2, message_size + n);
        tft.setTextSize(1,2);
        lcdPrint(0, 20, ST7735_WHITE, ST77XX_RED, String(VIN));
        tft.setTextSize(2);
        Init = 2;
      }
      else if (buf[n] == 0x61 && buf[n + 1] == DataRequest[1]) {
        Speed_engine = 256 * buf[n + 14] + buf[n + 15];
        Vitesse = (256 * buf[n + 16] + buf[n + 17])/100.0;
        lcdPrint(0, 70, ST7735_BLACK, ST77XX_GREEN, String(Speed_engine), 6);
        lcdPrint(0, 110, ST7735_BLACK, ST77XX_GREEN, String(Vitesse), 6);
      }
      // ТУТ ЧТО НИБУДЬ ДЕЛАЕМ КОГДА ПОЛУЧИЛИ СООБЩЕНИЕ ОТ ЭБУ
    }

    // если контрольная сумма не совпала:
    //else Serial.println("CRC fail!!!" );
    message_size = 0;
    header = 0;
    RESETheader_timer = 0;
    j = 3;
    checksum = 0;
  }



  // таймер ожидания байт (для успевания появления данных в буфере UART)
  if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1;

  // таймер сброса заголовка если данные оборвались во время приёма заголовка
  if (RESETheader_timer && curmillis - prevRESETheader > 500) {
    RESETheader_timer = 0;
    header = 0;
  }
}

Если подключить по такой схеме, то в Serial Port Monitor видно что ардуина посылает команды


А если вот так подключить, то команды не посылаются

ну в данном случае экран не важен. потому как если его убрать, то при подключении ардуино и ch341a к ПК в Serial Port Monitor приходят команды

ой ли? а земля как передаётся?

Сигнал по линии не может пройти по одному проводу. Нужен общий провод. Поэтому земли тоже нужно соединять

При подключении к ПК земли соединяются на ПК, а при отключении где?