호주에서 작성한 솔라카 전력 회로도



호주에 도착하고 작성한 회로도이다. 우리의 전력회로도는 이렇다. 

컨버터 2개 배터리 PV모듈 모터 모터컨트롤러 등등이 들어갔다.



물론 전력회로도에 들어가지 않는 많은 전장부 모듈들이있다.






모터전력과 태양광전력을 측정하는 모듈  - 중앙 MCU로 CAN을 전송한다.

전류센서의 레졸루션이 낮아서(1.25V) 계측용증폭기를 사용해서 레졸루션을 높였다. (3.0V)

MCU는 stm32f4 사용








배터리의 전류를 측정하고 SOC(베터리 전류 잔량)을 계산하는 MCU

차량의 전원이 끊어질 경우 외부 EEPROM에 SOC를 저장한다.

SOC는 전류적산을 이용한다.

역시 CAN통신을 이용하여 중앙 MCU에 데이터를 전송한다.

전류센서의 분해능을 높이기위해 계측용증폭기 TI사의  ina333 IC를 사용했고,

stm32f4의 ADC 분해능이 4095(12bit)를 16bit로 올리기위해 TI사의 ADC IC를 사용했다.




INA333의 회로도.

이득은 오른쪽 수식으로 나온다.




양방향 전압이 아닌 단방향 전압을 인가 가능하다.





2편에서 계속











 솔라카 - CAN BUS

람세스에 사용된 CAN 통신은 태양전지로부터 나오는 전력량을 확인 할 수 있도록 사용되었다. 람세스에 탑재 되어있는 MPPT Race version4의 경우 CAN 통신을 지원하기 때문에 CAN통신 단자에 2개의 선 과 CAN컨트롤러 공급 전압(최소 6V 최대18V) 2개의 선이 필요하다. 그리고 CAN 신호를 받아서 컴퓨터로 전송 할 수 있는 모듈이 필요하다. 모듈의 경우는 마이크로프로세서로 직접 만드는 방법과 시중에 팔고있는 CAN모듈을 구입하여 사용하는 방법이 있다. 람세스에서는 직접 CAN 신호를 받아서 컴퓨터의 시리얼 통신으로 전송 할 수 있는 마이크로프로세서로 만들어 사용했다.



STM32F407 - ATA6660

CAN통신의 관한 기술문서 이기 때문에 STM32f407 ARM coretex-m4 칩을 설명 하지 않겠다.

STM32f407 CAN트랜시버를 같이 사용해야만 CAN신호를 받고 보낼 수 있다. CAN트랜시버칩은 ATMEL사의 ATA6660을 사용했다.





선을 연결 해준 뒤,  STM32f407 칩에서 CAN 신호를 받아본다.



1.1    데이터 수신

프로세서에서 CAN데이터를 받을 수 있도록 코드를 작성하여 다운로드 해준다. 아래 코드는 STM32f407 칩에서 CAN 통신을 하기 위한 레지스터 초기 설정 부분이다. 이와 같이 설정해주고, 데이터를 보내면 CAN 통신이 활성화 된다.

void Can_Init()

{

         GPIO_InitTypeDef                 GPIO_InitStructure;

         CAN_InitTypeDef                   CAN_InitStructure;

         NVIC_InitTypeDef                 NVIC_InitStructure;

 

         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

         GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_CAN1);

         GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_CAN1);

 

         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;

         GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF;

         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

         GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

         GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

         GPIO_Init(GPIOB, &GPIO_InitStructure);

 

         CAN_DeInit(CAN1);

 

         CAN_InitStructure.CAN_TTCM = DISABLE;

         CAN_InitStructure.CAN_ABOM = DISABLE;

         CAN_InitStructure.CAN_AWUM = DISABLE;

         CAN_InitStructure.CAN_NART = DISABLE;

         CAN_InitStructure.CAN_RFLM = DISABLE;

         CAN_InitStructure.CAN_TXFP = ENABLE;

         CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;

 

        

         CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;

         CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;

         CAN_InitStructure.CAN_BS2 = CAN_BS2_1tq;

         CAN_InitStructure.CAN_Prescaler = 42;

        

         CAN_Init(CAN1, &CAN_InitStructure);

 

         CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

          

         NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;

         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

         NVIC_Init(&NVIC_InitStructure);

}

 

위 코드를 STM32f407칩에 다운로드 한 뒤 시리얼 통신으로 컴퓨터에서 CAN데이터를 받아보면 7바이트의 신호를 받을 수 있다.

 

1.2    C#프로그래밍

7바이트 신호들은 각 바이트 별로 정보가 들어있다. 각 정보는 MPPT데이터 시트 표(Figure 7)에 나와있다.

각 비트 별로 신호를 받았으면 시리얼 통신으로 컴퓨터에 데이터를 넘긴 후 C#프로그램을 제작해서 읽을 수 있는 눈금으로 표시한다. 아래 소스 코드는 각 바이트를 분석해서 원하는 정보를 얻는 과정이다.

 

buff[0] = buff[7];

                    buff[7] = (byte)(buff[7] & 0x03); //하위 2비트만 살림

                    vout_data = ((buff[2] + (256 * buff[3])) * 208.79) * 0.001;

                    vin_data = ((buff[6] + (256 * buff[7])) * 150.49) * 0.001;

                    iin_data = ((buff[4] + (256 * buff[5])) * 8.12) * 0.001;

                    power_data = iin_data * vin_data;

 






CAN 수신데이터가 시리얼 통신을 거치면서 가끔씩 오류가 날 경우도 있는데 이를 잡아주기 위해 소스코드에 데이터가 온전하지 못하면 넘어오지 못하게 하는 알고리즘도 제작을 해야한다. 위처럼 CAN 통신으로 에너지정보도 받을 수 있고, 차량내 통신으로도 CAN 을 사용할 수 도 있다











void Uart_Initialization(void)

{

static uint8 i;


/* disable interrupts */

    boolean              interruptState = IfxCpu_disableInterrupts();

    /* create module config */

    IfxAsclin_Asc_Config Uart_AscLin0;

    IfxAsclin_Asc_initModuleConfig(&Uart_AscLin0, &MODULE_ASCLIN0);


    /* set the desired baudrate */

    Uart_AscLin0.baudrate.prescaler    = 1;

    Uart_AscLin0.baudrate.baudrate     = 115200; /* FDR values will be calculated in initModule */

    Uart_AscLin0.baudrate.oversampling = IfxAsclin_OversamplingFactor_4;


    /* ISR priorities and interrupt target */

    Uart_AscLin0.interrupt.txPriority    = ISR_PRIORITY_ASCLIN0_TX;

    Uart_AscLin0.interrupt.rxPriority    = ISR_PRIORITY_ASCLIN0_RX;

    Uart_AscLin0.interrupt.erPriority    = ISR_PRIORITY_ASCLIN0_ER;

    Uart_AscLin0.interrupt.typeOfService = IfxSrc_Tos_cpu0;


    /* FIFO configuration */

    Uart_AscLin0.txBuffer     = AsclinAsc.ascBuffer.tx;

    Uart_AscLin0.txBufferSize = ASC_TX_BUFFER_SIZE;


    Uart_AscLin0.rxBuffer     = AsclinAsc.ascBuffer.rx;

    Uart_AscLin0.rxBufferSize = ASC_RX_BUFFER_SIZE;


const IfxAsclin_Asc_Pins pins = {

        NULL,                     IfxPort_InputMode_pullUp,        /* CTS pin not used */

        &IfxAsclin0_RXB_P15_3_IN, IfxPort_InputMode_pullUp,        /* Rx pin */

        NULL,                     IfxPort_OutputMode_pushPull,     /* RTS pin not used */

        &IfxAsclin0_TX_P15_2_OUT, IfxPort_OutputMode_pushPull,     /* Tx pin */

        IfxPort_PadDriver_cmosAutomotiveSpeed1

    };

    Uart_AscLin0.pins = &pins;




    /* initialize module */

    IfxAsclin_Asc_initModule(&AsclinAsc.drivers.asc0, &Uart_AscLin0);


    /* enable interrupts again */

    IfxCpu_restoreInterrupts(interruptState);




} /* End of Uart_Initialization */




void Uart_Put_Char(char c){


AsclinAsc.Uart_TxData[0] = c;

AsclinAsc.count = UART_TEST_DATA_SIZE;

IfxAsclin_Asc_write(&AsclinAsc.drivers.asc0,AsclinAsc.Uart_TxData, &AsclinAsc.count, TIME_INFINITE);

}


void Uart_Put_String(char *string){

    unsigned char i=0;


    while(string[i] != 0){       

    Uart_Put_Char(string[i++]);

    }                            

    Uart_Put_Char(0x0A);

}



hello world! 를 출력했다.





'프로젝트 > 자율주행모형차' 카테고리의 다른 글

라인스캔카메라 가우시안 필터, 엣지 디텍션  (1) 2018.06.13
라인스캔카메라  (11) 2018.06.07
라이다(RIDAR) tc237  (0) 2018.06.05
tc237 ADC(SAR)  (0) 2018.04.19
Infineon TC237 LCD 프로그램 업로드  (0) 2018.04.03


tc237을 사용하게 되서 시작했다.

LCD 데모 프로그램을 찾고있었는데 

하이텍 이클립스에서 기본예제으로 제공해준다.

프로젝트관리창에서 오른쪽 마우스를 클릭한뒤 new -> example 에 들어가면 LCD 예제 뿐 아니라 시리얼 예제도 있다.

'프로젝트 > 자율주행모형차' 카테고리의 다른 글

라인스캔카메라 가우시안 필터, 엣지 디텍션  (1) 2018.06.13
라인스캔카메라  (11) 2018.06.07
라이다(RIDAR) tc237  (0) 2018.06.05
tc237 ADC(SAR)  (0) 2018.04.19
tc237 uart tx 테스트  (3) 2018.04.17


모터에 전류가 어느정도 흐르는지 측정하기 위해서는 설치된 전류센서로 신호를 받아야한다. 현재 솔라카에서 사용하고 있는 전류센서[hass50]의 경우 출력 신호는 전압 신호로 되어있다.


<hass 50>


전류센서에서 출력되는 전압신호를 프로세서가 받기 위해서는 ADC(analog-to-digital converter)를 이용한다. 전압신호의 경우 노이즈가 많기 때문에 외곡이 있을 수 있고, 이 때문에 제대로된 전류측정값을 얻지 못 할 수도 있다. ADC노이즈를 줄이기위해서 솔라카에서는 디지털 필터를 사용했다. 가장 구현하기 쉬운방법이고, 개발 시간도 짧다.





'프로젝트 > 솔라카' 카테고리의 다른 글

솔라카 MPPT 전력량 CAN 데이터 수신  (0) 2018.04.17
2017 WSC 사진  (0) 2018.03.25
그래픽 oled (솔라카 대쉬보드)  (0) 2017.06.11
솔라카 고전압 측정회로  (0) 2017.05.16
MPPT 모니터링 프로그램  (0) 2016.11.25

can, rf 통신 모듈까지 장착한 후면 계기판 모습

저 모듈에서 방향지시등, 브레이크스위치 등등을 제어한다.







솔라카 계기판에 사용할 2.7인치 oled를 출력했다. (모델명: NHD-2.7-12864UCY3)

프로세서는 cortex-m3 계열 stm32f103을 사용

그래픽 라이브러리는 가장 많이 사용하는 u8g라이브러리를 이용했으며, 병렬방식이아닌 직렬방식으로 oled에 신호를 인가했다.

HAL라이브러리와 u8g라이브러리를 같이 사용했다.

속도는 직렬방식이라 느릴줄 알았는데, 계기판으로 사용하기에 전혀 지장이 없을정도로 업데이트가 빨랐다.

어느 각도에서든지 글자가 잘 보였고, 햇빛에서도 문제가 없어보였다.

이제 CAN트랜시버와 모듈화를 거쳐 CAN통신으로 값을 전달하면 값이 출력되게 만들예정이다.




아래는 데이터시트에서 발취한 시리얼 인터페이스








HAL라이브러리에 u8g_arm.c , u8g_arm.h 를 추가하여 소스를 추가한다.







u8g_arm.c
 #include "u8g_arm.h"  
 void u8g_Delay(uint16_t val)  
 {  
      HAL_Delay(val);  
 }  
 void u8g_MicroDelay(void)  
 {  
      HAL_Delay(1);  
 }  
 void u8g_10MicroDelay(void)  
 {  
      HAL_Delay(1);  
 }  
 uint8_t u8g_com_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr)  
 {  
  switch(msg)  
  {  
   case U8G_COM_MSG_STOP:  
    break;  
   case U8G_COM_MSG_INIT:  
    u8g_MicroDelay();  
    break;  
   case U8G_COM_MSG_ADDRESS:           /* define cmd (arg_val = 0) or data mode (arg_val = 1) */  
    u8g_10MicroDelay();  
    HAL_GPIO_WritePin(PORT, DC, arg_val);  
    u8g_10MicroDelay();  
    break;  
   case U8G_COM_MSG_CHIP_SELECT:  
    if ( arg_val == 0 )  
    {  
         HAL_Delay(1);  
         HAL_GPIO_WritePin(PORT, CS, GPIO_PIN_SET);  
    }  
    else  
      HAL_GPIO_WritePin(PORT, CS, GPIO_PIN_RESET);  
    u8g_MicroDelay();  
    break;  
   case U8G_COM_MSG_RESET:  
    break;  
   case U8G_COM_MSG_WRITE_BYTE:  
     HAL_SPI_Transmit(&SPI_HANDLER, &arg_val, 1, 10000);  
     while(HAL_SPI_GetState(&SPI_HANDLER) != HAL_SPI_STATE_READY);  
     u8g_MicroDelay();  
     break;  
   case U8G_COM_MSG_WRITE_SEQ:  
   case U8G_COM_MSG_WRITE_SEQ_P:  
    {  
         HAL_SPI_Transmit(&SPI_HANDLER, (uint8_t *)arg_ptr, arg_val, 10000);  
         while(HAL_SPI_GetState(&SPI_HANDLER) != HAL_SPI_STATE_READY);  
         u8g_MicroDelay();  
         arg_val = 0;  
    }  
    break;  
  }  
  return 1;  
 }  

u8g_arm.h:

 #ifndef _U8G_ARM_H  
 #define _U8G_ARM_H  
 #include "u8g.h"  
 #include "stm32f1xx_hal.h"  
 #define SPI_HANDLER hspi2 // use your SPI hadler  
 extern SPI_HandleTypeDef SPI_HANDLER;  
 #define DC GPIO_PIN_11  
 #define CS GPIO_PIN_12  
 #define PORT GPIOB  
 uint8_t u8g_com_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);  
 #endif  

and part of main.c:  메인소스는 재량껏 수정한다.
 #include "stm32f1xx_hal.h"  
   
 /* USER CODE BEGIN Includes */  
 #include "u8g.h"  
 #include "u8g_arm.h"  
 /* USER CODE END Includes */  
   
 /* Private variables ---------------------------------------------------------*/  
 SPI_HandleTypeDef hspi2;  
   
 TIM_HandleTypeDef htim1;  
   
 /* USER CODE BEGIN PV */  
 u8g_t u8g;  
 /* Private variables ---------------------------------------------------------*/  
   
 /* USER CODE END PV */  
   
 /* Private function prototypes -----------------------------------------------*/  
 void SystemClock_Config(void);  
 static void MX_GPIO_Init(void);  
 static void MX_SPI2_Init(void);  
   
   
 /* USER CODE BEGIN PFP */  
 /* Private function prototypes -----------------------------------------------*/  
   
 /* USER CODE END PFP */  
   
 /* USER CODE BEGIN 0 */  
   
 /* USER CODE END 0 */  
   
 int main(void)  
 {  
   
  /* USER CODE BEGIN 1 */  
   
  /* USER CODE END 1 */  
   
  /* MCU Configuration----------------------------------------------------------*/  
   
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */  
  HAL_Init();  
   
  /* Configure the system clock */  
  SystemClock_Config();  
   
  /* Initialize all configured peripherals */  
  MX_GPIO_Init();  
  MX_SPI2_Init();  
   
   
  /* USER CODE BEGIN 2 */  
  u8g_InitComFn(&u8g, &u8g_dev_ssd1306_128x64_hw_spi, u8g_com_hw_spi_fn); //이부분은 자신의 디스플레이에 맞춰야함 
  HAL_Delay(100);  
  /* USER CODE END 2 */  
   
  /* Infinite loop */  
  /* USER CODE BEGIN WHILE */  
  while (1)  
  {  
  /* USER CODE END WHILE */  
   
  /* USER CODE BEGIN 3 */  
       u8g_FirstPage(&u8g);  
       do  
       {  
            u8g.font = u8g_font_profont22;  
            u8g_DrawStr(&u8g, 20, 55, "Hello");  
       } while ( u8g_NextPage(&u8g) );  
    HAL_Delay(100);  
  }  
  /* USER CODE END 3 */  
   
 }  




spi+hal+u8g 

도움받은곳 http://elastic-notes.blogspot.kr/p/stm32-spi-oled-ssd1306-u8glib-cubemx.html






'프로젝트 > 솔라카' 카테고리의 다른 글

2017 WSC 사진  (0) 2018.03.25
솔라카 전류측정[adc 정확도 향상]  (0) 2017.07.10
솔라카 고전압 측정회로  (0) 2017.05.16
MPPT 모니터링 프로그램  (0) 2016.11.25
솔라카 더미카  (0) 2016.10.15








INA333 계측용 증폭기를 사용했다. 전압분배 저항은 200k 근처로 사용해서 내부임피던스를 높이고, 용량이 큰 저항을 사용해야한다. 

pspice 시뮬레이션 결과 배터리 전압이 70V일 경우 2.5V가 출력 되고 배터리 전압이 121.8V 일 경우 4.5V가 출력이 된다.

MCU의 12bit ADC로 배터리의 전압을 측정 할 수 있다. 하지만 배터리는 고전압으로 제어회로에 심각한 피해를 줄 수 있고, BLDC모터의 토크리플 때문에 노이즈로 센싱 성능이 떨어진다. 그래서 절연 과정과 아날로그 필터, 디지털 필터가 필요하다. 

'프로젝트 > 솔라카' 카테고리의 다른 글

솔라카 전류측정[adc 정확도 향상]  (0) 2017.07.10
그래픽 oled (솔라카 대쉬보드)  (0) 2017.06.11
MPPT 모니터링 프로그램  (0) 2016.11.25
솔라카 더미카  (0) 2016.10.15
방향지시등 회로 - 555타이머  (0) 2016.09.01

솔라셀 상판 전력데이터가 필요했는데

전력측정하는 시스템을 만들자니 번거럽고해서, mppt에서 나오는 CAN데이터를 받아왔다.

 

 

구름이 걷힐때 까지 기다리면서 

??

 

구름이 걷혔다.

 

 

 

 

 

해가 그리 밝지 않았다..

 

 

 

 

buff[0] = buff[7];
buff[7] = (byte)(buff[7] & 0x03); //하위 2비트만 살림
vout_data = ((buff[2] + (256 * buff[3])) * 208.79) * 0.001;
vin_data = ((buff[6] + (256 * buff[7])) * 150.49) * 0.001;
iin_data = ((buff[4] + (256 * buff[5])) * 8.12) * 0.001;
power_data = iin_data * vin_data;

 

 

 

 

 

c# 으로 간단하게 제작

 

'프로젝트 > 솔라카' 카테고리의 다른 글

솔라카 전류측정[adc 정확도 향상]  (0) 2017.07.10
그래픽 oled (솔라카 대쉬보드)  (0) 2017.06.11
솔라카 고전압 측정회로  (0) 2017.05.16
솔라카 더미카  (0) 2016.10.15
방향지시등 회로 - 555타이머  (0) 2016.09.01


대회전 연습용 차량이다.

+ Recent posts