/*
* HX711.c
*
* Created: 2025-01-14 오전 10:15:09
* Author: KyKi
*/
#include "cdef.h"
#include "HX711.h"
#include <avr\io.h>
#include <util\delay.h>
sint32 HX711_s32Raw[HX711_CH_count];
void HX711_Clk(uint8 clk)
{
if (clk==0)
{
ClrBit( PORTC , BIT1 + BIT3 + BIT5 + BIT7 );
ClrBit( PORTA , BIT7 );
} else
{
SetBit( PORTC , BIT1 + BIT3 + BIT5 + BIT7 );
SetBit( PORTA , BIT7 );
}
}
uint8 HX711_ReadData(uint8 ch)
{
uint8 ret;
ret = 0;
if (ch==0) ret = (((PINC & BIT0)>0)? (1) : 0);
if (ch==1) ret = (((PINC & BIT2)>0)? (1) : 0);
if (ch==2) ret = (((PINC & BIT4)>0)? (1) : 0);
if (ch==3) ret = (((PINC & BIT6)>0)? (1) : 0);
if (ch==4) ret = (((PING & BIT2)>0)? (1) : 0);
return ret;
}
void INIT_HX711(void)
{
ClrBit( PORTC , BIT1 + BIT3 + BIT5 + BIT7 ); // clock OUTPUTs
SetBit( DDRC , BIT1 + BIT3 + BIT5 + BIT7 );
ClrBit( PORTA , BIT7 );
SetBit( DDRA , BIT7 );
ClrBit( DDRC , BIT0 + BIT2 + BIT4 + BIT6 ); // din INPUT
SetBit( PORTC , BIT0 + BIT2 + BIT4 + BIT6 ); // Pulled UP
ClrBit( DDRG , BIT2 );
SetBit( PORTG , BIT2 );
}
void Task_HX711(void)
{
uint8 r, clk_counts;
uint8 timeout = 0;
sint32 bitidx;
sint32 s32data[HX711_CH_count];
// CH=A gain=64 --> clk pulse = 27 pulses
// rate = high = 80Hz sampling = 13msec
for (r=0;r<HX711_CH_count;r++)
{
s32data[r] = 0;
}
timeout = 0;
HX711_Clk(0); // clock 0
r = HX711_ReadData(0) + HX711_ReadData(1) + HX711_ReadData(2) + HX711_ReadData(3) + HX711_ReadData(4);
while ((r>0) && (timeout<20)) // wait for all zero of data input
{
_delay_ms(1);
r = HX711_ReadData(0) + HX711_ReadData(1) + HX711_ReadData(2) + HX711_ReadData(3) + HX711_ReadData(4);
timeout++;
}
if (r==0) // all data ready
{
_delay_us(1);
bitidx = 0x80000000; // setup signed 32bit;
for (clk_counts=0;clk_counts<27;clk_counts++) // make 27 clock pulses
{
HX711_Clk(1);
_delay_us(1);
if (clk_counts<24) // read out 24 bit
{
for (r=0;r<HX711_CH_count;r++)
{
if (HX711_ReadData(r)==1)
{
s32data[r] = s32data[r] | bitidx;
}
}
bitidx = bitidx >> 1;
}
HX711_Clk(0);
_delay_us(1);
}
for (r=0;r<HX711_CH_count;r++)
{
HX711_s32Raw[r] = s32data[r] / (sint32)256; // convert to 24bit
}
}
}
/*
* HX711.h
*
* Created: 2025-01-14 오전 10:14:54
* Author: KyKi
*/
#ifndef HX711_H_
#define HX711_H_
#include "cdef.h"
#define HX711_X (0)
#define HX711_Y (1)
#define HX711_Z (2)
#define HX711_Ref (3)
#define HX711_Temp (4)
#define HX711_CH_count (5)
extern sint32 HX711_s32Raw[HX711_CH_count];
extern void INIT_HX711(void);
extern void Task_HX711(void);
#endif /* HX711_H_ */
#include "cdef.h"
#include <avr\io.h>
#include <avr\interrupt.h>
#include <avr\wdt.h>
#include <avr\eeprom.h>
#include <util\delay.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include "uart2.h"
#include "Max1167.h"
#include "HX711.h"
uint32 CalFactor[4];
/* ************************************
PIN configuration
Max1167
DIN = C3
DOUT = C2
SCLK = C1
CS = C0
Batt voltage = ADC7 PF7
LCD TX = PE1 (TX0)
LCD RX = PE0 (RX0)
COMM TX = PD3 (TX1)
COMM RX = PD2 (RX1)
****************************************** */
uint16 SaveEEP_Reqeust = 0;
uint16 Stream_Reqeust = 0;
uint16 Cal_Reqeust = 0;
#define RxStrings UART2_CH1_au8RxBuff
#define RxLength UART2_CH1_u8RxLen
void Comm_RX_Parser(void)
{
uint8 r,k;
char * param[5];
char cmd;
double param1,param2,param3,param4;
param[0]=RxStrings;
k=1;
for (r=0;r<RxLength;r++)
{
if (RxStrings[r]==',')
{
RxStrings[r]=0;
param[k] = RxStrings+r+1;
k = k + 1;
}
}
cmd = param[0][0];
param1 = atof( param[1] );
param2 = atof( param[2] );
param3 = atof( param[3] );
param4 = atof( param[4] );
if (cmd=='W') /* Write Cal factors */
{
CalFactor[0] = (uint32)(param1*10000);
CalFactor[1] = (uint32)(param2*10000);
CalFactor[2] = (uint32)(param3*10000);
CalFactor[3] = (uint32)(param4*10000);
SaveEEP_Reqeust = 1;
}
if (cmd=='S') /* Read Cal factors */
{
Stream_Reqeust = 500;
}
if (cmd=='T') /* Read Cal factors */
{
Stream_Reqeust = 0;
}
if (cmd=='C') /* Read Cal factors */
{
Cal_Reqeust = Cal_Reqeust + 1;
}
}
void CMD_RX_Parser(void)
{
/*
if ((RXCHAR[0]=='U') && (RXCHAR[1]=='0')) RemoteSw_Up = 0;
if ((RXCHAR[0]=='U') && (RXCHAR[1]=='1')) RemoteSw_Up = 1;
if ((RXCHAR[0]=='D') && (RXCHAR[1]=='0')) RemoteSw_Dn = 0;
if ((RXCHAR[0]=='D') && (RXCHAR[1]=='1')) RemoteSw_Dn = 1;
if ((RXCHAR[0]=='L') && (RXCHAR[1]=='0')) RemoteSw_Local = 0;
if ((RXCHAR[0]=='L') && (RXCHAR[1]=='1')) RemoteSw_Local = 1;
if ((RXCHAR[0]=='R') && (RXCHAR[1]=='0')) RemoteSw_RunStop = 0;
if ((RXCHAR[0]=='R') && (RXCHAR[1]=='1')) RemoteSw_RunStop = 1;
if ((RXCHAR[0]=='P') && (RXCHAR[1]=='0')) RemoteSw_Purge = 0;
if ((RXCHAR[0]=='P') && (RXCHAR[1]=='1')) RemoteSw_Purge = 1;
*/
}
void SaveEEPROM(void)
{
eeprom_write_dword( (uint32_t *)0 , 0xFFFFFFFF );
eeprom_write_dword( (uint32_t *)4 , 0xFFFFFFFF );
eeprom_write_dword( (uint32_t *)8 , 0xFFFFFFFF );
eeprom_write_dword( (uint32_t *)12 , 0xFFFFFFFF );
eeprom_write_dword( (uint32_t *)0 , CalFactor[0] );
eeprom_write_dword( (uint32_t *)4 , CalFactor[1] );
eeprom_write_dword( (uint32_t *)8 , CalFactor[2] );
eeprom_write_dword( (uint32_t *)12 , CalFactor[3] );
}
void LoadEEPROM(void)
{
CalFactor[0] = eeprom_read_dword( (uint32_t *)0 );
CalFactor[1] = eeprom_read_dword( (uint32_t *)4 );
CalFactor[2] = eeprom_read_dword( (uint32_t *)8 );
CalFactor[3] = eeprom_read_dword( (uint32_t *)12 );
if ((CalFactor[0]<10) || (CalFactor[0]>90000)) CalFactor[0] = 10000;
if ((CalFactor[1]<10) || (CalFactor[1]>90000)) CalFactor[1] = 10000;
if ((CalFactor[2]<10) || (CalFactor[2]>90000)) CalFactor[2] = 10000;
if ((CalFactor[3]<10) || (CalFactor[3]>90000)) CalFactor[3] = 10000;
}
#define DGUS_RUN_SW 0x2131
#define DGUS_STOP_SW 0x4032
#define DGUS_PSTART_SW 0x2333
#define DGUS_PSTOP_SW 0x2434
#define DGUS_LOCAL_SW 0x2535
#define DGUS_RMT_SW 0x5E36
uint8 DGUS_RxBuff[20];
void DGUS_Rx_Frame_Run(void)
{
/*
// first is len. others is data
uint16 addr = 0;
uint16 va = 0;
addr = (((uint16)DGUS_RxBuff[2]) << 8) + (uint16)DGUS_RxBuff[3];
va = (((uint16)DGUS_RxBuff[5]) << 8) + (uint16)DGUS_RxBuff[6];
if (addr==0) // switch input
{
Local_Remote_Saved = RemoteSw_Local;
if (va==DGUS_RUN_SW) RemoteSw_RunStop = 1;
if (va==DGUS_STOP_SW) RemoteSw_RunStop = 0;
if (va==DGUS_PSTART_SW) RemoteSw_Purge = 1;
if (va==DGUS_PSTOP_SW) { RemoteSw_Purge = 0; if (Fan3MinCounter>1) {Fan3MinCounter=1;} }
if (va==DGUS_LOCAL_SW) { RemoteSw_Local = 0; }
if (va==DGUS_RMT_SW) { RemoteSw_Local = 1; }
if (Local_Remote_Saved != RemoteSw_Local)
{
if (RemoteSw_Local==1) { Last_SV_DGUS = SV; } // to remote ?
if (RemoteSw_Local==0) { SV = Last_SV_DGUS; LastContentsCrc=0xff; } // to local ?
}
}
if (addr==0x5000) { if (va>SV_range) va=SV_range; SV = va; LastContentsCrc=0xff; LocalSV=SV; }
if (addr==0x5110) SV_range = va;
if (addr==0x5120) Control_Voltage = va;
if (addr==0x5130)
{
Control_Freq = va;
if (va==1979) // special routine for reset total_timer by Freq set by 1979
{
if (Totaltime!=0)
{
Totaltime = 0;
Request_SaveEEPROM();
}
}
}
if (addr==0x5140) Control_Gain = va;
*/
}
uint8 headercheck_1 = 0xFF;
uint8 headercheck_2 = 0xFF;
uint8 header_ok = 0;
uint16 DGUS_timeout = 0;
uint8 DGUS_Rx_Len = 0;
void Rx_Char( uint8 rxc )
{
if (header_ok==0)
{
headercheck_1 = headercheck_2;
headercheck_2 = rxc;
if ((headercheck_1==0x5A) && (headercheck_2==0xA5))
{
header_ok = 1;
DGUS_timeout = 0;
DGUS_Rx_Len = 0;
headercheck_1 = 0;
headercheck_2 = 0;
}
} else
{
DGUS_RxBuff[DGUS_Rx_Len] = rxc;
DGUS_Rx_Len++;
if (DGUS_Rx_Len>DGUS_RxBuff[0])
{
header_ok = 0;
DGUS_timeout = 0;
DGUS_Rx_Len = 0;
headercheck_1 = 0;
headercheck_2 = 0;
DGUS_Rx_Frame_Run();
}
}
}
uint8 DGUS_TX_BUFF[20];
void DGUS_TX(uint8 len , uint8 * buff_)
{
uint8 r;
DGUS_TX_BUFF[0] = 0x5A;
DGUS_TX_BUFF[1] = 0xA5;
DGUS_TX_BUFF[2] = len;
for (r=0;r<len;r++)
{
DGUS_TX_BUFF[r+3] = buff_[r];
}
UART_Put_Buff(len+3,DGUS_TX_BUFF);
}
uint8 dgusstr[10];
void DGUS_Write_Var4(uint16 addr, sint32 value)
{
dgusstr[0] = 0x82;
dgusstr[1] = (addr >> 8);
dgusstr[2] = (addr & 0x00FF);
dgusstr[3] = (value >> 24);
dgusstr[4] = (value >> 16);
dgusstr[5] = (value >> 8);
dgusstr[6] = (value & 0x00FF);
DGUS_TX(7,dgusstr);
}
void DGUS_Write_Var(uint16 addr, sint16 value)
{
dgusstr[0] = 0x82;
dgusstr[1] = (addr >> 8);
dgusstr[2] = (addr & 0x00FF);
dgusstr[3] = (value >> 8);
dgusstr[4] = (value & 0x00FF);
DGUS_TX(5,dgusstr);
}
void Change_DGUS_Screen( uint8 screen_num )
{
// 5a a5 07 82 00 84 5a 01 00 00
dgusstr[0] = 0x82;
dgusstr[1] = 0x00;
dgusstr[2] = 0x84;
dgusstr[3] = 0x5a;
dgusstr[4] = 0x01;
dgusstr[5] = 0x00;
dgusstr[6] = screen_num;
DGUS_TX(7,dgusstr); _delay_ms(10);
}
void vInit(void)
{
// vInitMax1167();
INIT_HX711();
UART2_vReset();
UART2_vOpenPort(0 , 9600 , CONF_8BIT_NOPAR_1STOP); // CH0 = LCD
UART2_vOpenPort(1 , 9600 , CONF_8BIT_NOPAR_1STOP); // CH0 = COMM
// RTC Clock Setup
TIMSK = 1; // timer0 overflow intr enable.
TCCR0 = 5; // clk / 256 / 128 = 450 Hz
// setup ADC
ADMUX = 0x46; // 01000110
ADCSRA = 0xD7; // 10000111 // Start ADC
}
uint16 tenmiliseccounter;
uint8 SecEvent;
ISR(TIMER0_OVF_vect)
{
tenmiliseccounter++;
if (tenmiliseccounter>=450)
{
tenmiliseccounter = 0;
SecEvent++;
}
}
#define GAIN_1 0
#define GAIN_2 1
uint8 ADC_ConversionStarted = 0;
void ADC_vStart(uint8 ch , uint8 gain)
{
// ADCSRA = 0b11010111; /* ADC conversion start with single start. Prescale = 115kHz */
// ADCSRA = 0b01010111; /* turn off ADC */
ADCSRA = 0b10010111;
ADMUX = (0b01000000) | ch; /* REF = 01 : external AVCC REF, */
ADCSRA = 0b11010111; /* ADC conversion start with single start. Prescale = 115kHz */
ADC_ConversionStarted = 1;
}
uint16 ADC_u16ReadADC(void)
{
uint16 lo,hi;
if (ADC_ConversionStarted==0)
{
return (0);
} else
{
while ((ADCSRA & 0x40) > 0) /*wait until conversion completed*/
{
}
ADC_ConversionStarted = 0;
lo = ADCL;
hi = ADCH;
// ADCSRA = 0b01010111;
return ((hi<<8) | (lo));
}
}
float fADC_Raw[5];
uint32 RefV , BattV;
float X,Y,Z,T;
float X_,Y_,Z_,T_;
char text[50];
float Read_Avg(uint8 ch)
{
float raw;
uint16 r;
raw = 0;
for (r=0;r<320;r++)
{
raw = raw + (float)ReadMax1167(ch);
}
raw = raw / 320.0f;
return (raw);
}
signed int main(void)
{
cli(); // global intr disable
wdt_disable();
vInit();
sei();
LoadEEPROM();
_delay_ms(500);
Task_HX711();
while (1)
{
Task_HX711();
fADC_Raw[0] = HX711_s32Raw[HX711_X];
fADC_Raw[1] = HX711_s32Raw[HX711_Y];
fADC_Raw[2] = HX711_s32Raw[HX711_Z];
fADC_Raw[3] = HX711_s32Raw[HX711_Temp];
fADC_Raw[4] = HX711_s32Raw[HX711_Ref]; // 2.5V ref
// read raw analog data
ADC_vStart( 6 , 0 ); _delay_ms(20);
RefV = ADC_u16ReadADC();
ADC_vStart( 7 , 0 ); _delay_ms(20);
BattV = ADC_u16ReadADC();
BattV = round(100.0f * 5.0649f * ((float)BattV) / 1023.0f);
RefV = round(100.0f * 5.0649f * ((float)RefV) / 1023.0f);
if (fADC_Raw[4]>0.0f)
{
X = 2.5f*fADC_Raw[0]/fADC_Raw[4]; // calc to Voltage
X = (X-2.5f) * 45.4545f * ((float)CalFactor[0])/10000.0f; // 2.5V is Zero, 45.45uT/V is SCale
Y = 2.5f*fADC_Raw[1]/fADC_Raw[4]; // calc to Voltage
Y = (Y-2.5f) * 45.4545f * ((float)CalFactor[1])/10000.0f; // 2.5V is Zero, 45.45uT/V is SCale
Z = 2.5f*fADC_Raw[2]/fADC_Raw[4]; // calc to Voltage
Z = (Z-2.5f) * 45.4545f * ((float)CalFactor[2])/10000.0f; // 2.5V is Zero, 45.45uT/V is SCale
T = 2.5f*fADC_Raw[3]/fADC_Raw[4]; // calc to Voltage
T = (T-2.5f)*1000 * 0.025f * ((float)CalFactor[3])/10000.0f-1.0f; // 2.5V is Zero, 0.25oC/mV 273.17K = 0oC
}
X_=X_*0.0 + X*1.0;
Y_=Y_*0.0 + Y*1.0;
Z_=Z_*0.0 + Z*1.0;
T_=T_*0.0 + T*1.0;
DGUS_Write_Var4(0x5000,(sint32)round(X_*1000)); _delay_ms(5);
DGUS_Write_Var4(0x5010,(sint32)round(Y_*1000)); _delay_ms(5);
DGUS_Write_Var4(0x5020,(sint32)round(Z_*1000)); _delay_ms(5);
DGUS_Write_Var(0x5030,(sint16)round(T_*10)); _delay_ms(5);
DGUS_Write_Var(0x5040,(sint16)BattV); _delay_ms(25);
if (Stream_Reqeust>0)
{
UART_vPut(1,"$I,");
dtostrf(X_,8,3,text); UART_vPut(1,text); UART_vPut(1,",");
dtostrf(Y_,8,3,text); UART_vPut(1,text); UART_vPut(1,",");
dtostrf(Z_,8,3,text); UART_vPut(1,text); UART_vPut(1,",");
dtostrf(T_,5,1,text); UART_vPut(1,text); UART_vPut(1,",");
dtostrf(((float)BattV)/100.0f,5,2,text); UART_vPut(1,text); UART_vPut(1,",");
dtostrf(((float)RefV)/100.0f,5,2,text); UART_vPut(1,text); UART_vPut(1,"#\r\n");
Stream_Reqeust = Stream_Reqeust - 1;
}
if (Cal_Reqeust>0)
{
UART_vPut(1,"$C,");
dtostrf(((float)CalFactor[0])/10000.0,6,4,text); UART_vPut(1,text); UART_vPut(1,",");
dtostrf(((float)CalFactor[1])/10000.0,6,4,text); UART_vPut(1,text); UART_vPut(1,",");
dtostrf(((float)CalFactor[2])/10000.0,6,4,text); UART_vPut(1,text); UART_vPut(1,",");
dtostrf(((float)CalFactor[3])/10000.0,6,4,text); UART_vPut(1,text); UART_vPut(1,"#\r\n");
Cal_Reqeust = Cal_Reqeust - 1;;
}
if (SaveEEP_Reqeust)
{
SaveEEP_Reqeust = 0;
SaveEEPROM();
Cal_Reqeust = 1;
}
}
return (0);
}
/* protocol examples
$I, 20.533, 8.935, 48.418, 22.9, 4.27, 2.51#
$C,1.0000,1.0000,1.0000,1.0000#
*/