Project showcase
RC Submarine

RC Submarine © GPL3+

How to make a radio-controlled submarine with a video camera

  • 3,985 views
  • 4 comments
  • 30 respects

Components and supplies

Necessary tools and machines

4418162
Drill, Screwdriver
Hy gluegun
Hot glue gun (generic)
09507 01
Soldering iron (generic)

About this project

Everyone can build a submarine. To assemble this design from a tool, only a screwdriver and a hot glue gun were required. The design consists of several modules:

  • module with electronics
  • 2 cylinders for storage of compressed air
  • 2 ballast tanks (bow and stern)
  • 2 capacities for battery
  • 2 tanks for ballast to adjust the buoyancy.

As propulsors, 4 micropumps for water were used.

Schematic diagram:

Universal Remote Control Arduino

Electronics is assembled on the basis of the Russian version of the Arduino board called Iskra Nano Pro. The board is made on the AT Mega 328PB microcontroller. Unlike the original Arduino board and its Chinese copies, the board has a 2nd hardware UART on board, which allows you to connect the gps module to determine the coordinates of the submarine using satellite navigation and it allows you to use all the analog pins as digital ones - so I have 2 free pins for connecting sensors. In the future, the submarine plans to install 2 engines with screws. To save pins (usually 6 pins are required to connect the L293D driver), the CD4069UBE logic chip is used. The battery charge is monitored by the INA219 current sensor. The IMU sensor allows you to detect tilt angles in three axes. (2 axes will be used - one for the trim angle and the second for automatic heading). Power is supplied from a separate stabilizer L4941BV with a minimum difference between input and output voltage, which allows for stable operation of the equipment. For radio communication, the HC-12 radio module is used, which perfectly catches a signal even under water. 4 pumps, 2 microcompressors and 2 solenoid valves are powered from the Darlington ULN2803 assembly.

Open water tests, the process of immersion, ascent and the operation of electronics under water can be seen in this video:

Open water tests

Code

UartAndPinConfig.hArduino
#include "Arduino.h"

#define  SetBit(reg, bita)         reg |= (1<<bita)            
#define  ClearBit(reg, bita)       reg &= (~(1<<bita))
#define  InvBit(reg, bita)         reg ^= (1<<bita)
#define  BitIsSet(reg, bita)       ((reg & (1<<bita)) != 0)
#define  BitIsClear(reg, bita)     ((reg & (1<<bita)) == 0)

// Arduino Duemilanove, Diecimila, and NG
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)

#define LedPinOut() DDRB  |= (1<<5)
#define LedPinOn()  PORTB |= (1<<5)
#define LedPinOFF() PORTB &= (~(1<<5))

// Arduino Mega
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

#define LedPinOut() DDRB  |= (1<<7)
#define LedPinOn()  PORTB |= (1<<7)
#define LedPinOFF() PORTB &= (~(1<<7))

// Leonardo
#elif defined(__AVR_ATmega32U4__)

#define LedPinOut() DDRC  |= (1<<7)
#define LedPinOn()  PORTC |= (1<<7)
#define LedPinOFF() PORTC &= (~(1<<7))

// anything else
#else
#error "Board not supported"
#endif

#if defined(Serial_0) 			//UART0

#if defined(UBRRH) && defined(UBRRL) 
	#define  UDRn     UDR
	#define  UBRRnH   UBRRH
	#define  UBRRnL   UBRRL
	#define  UCSRnA   UCSRA 
	#define  UCSRnB   UCSRB  
	#define  UCSRnC   UCSRC      
#else
	#define  UDRn     UDR0
	#define  UBRRnH   UBRR0H
	#define  UBRRnL   UBRR0L
	#define  UCSRnA   UCSR0A 
	#define  UCSRnB   UCSR0B  
	#define  UCSRnC   UCSR0C
#endif

#if defined(USART_RX_vect)
  #define BYTEin USART_RX_vect  
#elif defined(USART0_RX_vect)
  #define BYTEin USART0_RX_vect
#elif defined(USART_RXC_vect)
  #define BYTEin USART_RXC_vect //ATmega8
#else
  #error "Board not supported"
#endif

#endif  			  			//UART0


#if defined(Serial_1) 			//UART1

	#define  UDRn     UDR1
	#define  UBRRnH   UBRR1H
	#define  UBRRnL   UBRR1L
	#define  UCSRnA   UCSR1A 
	#define  UCSRnB   UCSR1B  
	#define  UCSRnC   UCSR1C 
	
	#if defined(UART1_RX_vect)
		#define	BYTEin UART1_RX_vect
	#elif defined(USART1_RX_vect)
		#define BYTEin USART1_RX_vect
	#else
	#error "Board not supported"
	#endif
		
#endif							//UART1


#if defined(Serial_2)			//UART2

	#define  UDRn     UDR2
	#define  UBRRnH   UBRR2H
	#define  UBRRnL   UBRR2L  
	#define  UCSRnA   UCSR2A 
	#define  UCSRnB   UCSR2B  
	#define  UCSRnC   UCSR2C 
	#define  BYTEin   USART2_RX_vect
			
#endif							//UART2


#if defined(Serial_3)			//UART3

	#define  UDRn     UDR3
	#define  UBRRnH   UBRR3H
	#define  UBRRnL   UBRR3L
	#define  UCSRnA   UCSR3A 
	#define  UCSRnB   UCSR3B  
	#define  UCSRnC   UCSR3C 
	#define  BYTEin   USART3_RX_vect
			
#endif							//UART3

#if !defined(TXC0)
#if defined(TXC)
// Some chips like ATmega8 don't have UPE, only PE. The other bits are
// named as expected.
#if !defined(UPE) && defined(PE)
#define UPE PE
#endif
// On ATmega8, the uart and its bits are not numbered, so there is no TXC0 etc.
#define TXC0 TXC
#define RXEN0 RXEN
#define TXEN0 TXEN
#define RXCIE0 RXCIE
#define UDRIE0 UDRIE
#define U2X0 U2X
#define UPE0 UPE
#define UDRE0 UDRE
#elif defined(TXC1)
// Some devices have uart1 but no uart0
#define TXC0 TXC1
#define RXEN0 RXEN1
#define TXEN0 TXEN1
#define RXCIE0 RXCIE1
#define UDRIE0 UDRIE1
#define U2X0 U2X1
#define UPE0 UPE1
#define UDRE0 UDRE1
#else
#error No UART found in HardwareSerial.cpp
#endif
#endif // !defined TXC0
Serial27bTransmitter.hArduino
#include "Arduino.h"
#include "UartAndPinConfig.h"

const uint8_t transmStart = 129;  	//   
const uint8_t transmEnd = 130;	  	//   

const uint8_t receiverStart =254; 	//   	 
const uint8_t receiverEnd = 255;  	//   

//       
volatile uint32_t Serial34bSendTimeOUT;
//    		
volatile uint32_t Serial34bTimeCore = 0;
//   true /   false
volatile boolean tTimeOut = true;
//    
volatile uint8_t tErrTime = 0;
//    
volatile uint8_t tErrCRC = 0;
//    
volatile uint8_t BYTEinCount = 0;
//   
volatile uint8_t inUart_arr[32];

ISR (TIMER0_COMPA_vect) {
Serial34bTimeCore ++;

	if (Serial34bTimeCore >	Serial34bSendTimeOUT) {		//   
	Serial34bTimeCore = 0;

	if (tTimeOut) {										//  /  !!!
	tTimeOut = false;
	
//       UART
uint8_t uart_arr[32];
for (uint8_t i = 0; i <= 31; i++) uart_arr[i]=0;

//    b8_arr[28];
uint8_t b8_arr[28];
//      
b8_arr[0] = 0;
for (uint8_t i = 1; i <= 27; i++) b8_arr[i] = transm_arr[i-1];

//         
int8_t uartCount = 0;
for (uartCount = 27; uartCount >= 0; uartCount--) {
    if (b8_arr[uartCount] != 0) break; 		//   uartCount 
  }

if (uartCount != -1) { 		//    -     
// 
//           
uint16_t crc16 = 0;	
uint8_t crc8 = 0;
for (uint8_t i = 1; i <= uartCount; i++) crc16 = crc16 + b8_arr[i] * 44111;
crc8 = crc16 & 255;	
b8_arr[0] = crc8;

	//  8-    7- 
	uint8_t k = 0;
	uint8_t q = 1; 		
   for (uint8_t j = 0; j <= 24; j=j+8) { // 0, 8, 16, 24  
	for (uint8_t i = k; i <= k+6; i++) { // 0...6 / 7...13 /14...20 / 21...27 / 
	uart_arr[i+q] = b8_arr[i];
	uart_arr[i+q] &= B01111111;
	b8_arr[i]     &= B10000000;
	uart_arr[j] |= b8_arr[i];
	uart_arr[j] >>= 1;
	} 									// 0...6 / 7...13 /14...20 / 21...27 /  
  if (uartCount<j) break;	    		//    
  uartCount ++;  
  k = k + 7; 
  q = q + 1;
   }								 	// 0, 8, 16, 24      
}		//        UART uart_arr[32] 
	
	//    
	while ( !( UCSRnA & (1<<UDRE0)) );
	UDRn = receiverStart;
	//  uart_arr[32]		
	for (int8_t i = 0; i <= uartCount; i++) {
	while ( !( UCSRnA & (1<<UDRE0)) );
	UDRn = uart_arr[i];
	}	
	//    
	while ( !( UCSRnA & (1<<UDRE0)) );
	UDRn = receiverEnd;
	
	}  else { 											//     transmTOUT = false;
	//    
	tTimeOut = true;
	//     
	tErrTime++;
	//    
	LedPinOFF();									
}
	}													//   													
}														//   											

ISR (BYTEin) {										    	
	//     !!!
	uint8_t	dat = 0;										
	dat = UDRn;

	if (transmStart == dat){								//     
	BYTEinCount = 0;
	for (uint8_t i = 0; i <= 31; i++) inUart_arr[i] = 0; 	//   inUart_arr[32]
	return;
	}
	
	if (transmEnd == dat){									//      
		
	if (BYTEinCount == 0) {								    //       									
	for (uint8_t i = 0; i <= 26; i++) receiv_arr[i] = 0;	//     
	Serial34bTimeCore = 0;									//   
    LedPinOn();										//       -  
	tTimeOut = true;										//    	
	return;
	} else {											
	uint8_t b8_arr[28];										//   
	for (uint8_t i = 0; i <= 27; i++) b8_arr[i] = 0;		//   	
   
   //  	
   uint8_t k = 0;
   uint8_t q = 1;		
   for (uint8_t j = 0; j <= 27; j=j+7) { // 0, 7, 14, 31	
	for (uint8_t i = j; i <= j+6; i++) {   // 0...6 / 7...13 /14...20 / 21...27 /
		b8_arr[i] = inUart_arr[k];
		b8_arr[i] <<= (7+j-i);
		b8_arr[i] &= B10000000;
		b8_arr[i] |= inUart_arr[i+q];	
	}									   // 0...6 / 7...13 /14...20 / 21...27 /			   
   k = k + 8;
   q = q + 1;  
  }										   // 0, 7, 14, 31										   
	//  

	//  
	uint16_t crc16 = 0;
	for (int i = 1; i <= 27; i++) crc16 = crc16 + b8_arr[i] * 44111;
	uint8_t crc8 = 0;
	crc8 = crc16 & 255;	
	//  
	if (b8_arr[0] == crc8) {
	//    !!!  
	for (int i = 0; i <=26; i++) receiv_arr[i] = b8_arr[i+1];
	//  
	LedPinOn();
	//   
	Serial34bTimeCore = 0;
	//    
	tTimeOut = true;
	} else {
	//  
	LedPinOFF();
	//     
	tErrCRC++;
	}
	}
	return;
	}	
	//      
	inUart_arr[BYTEinCount] = dat;
    BYTEinCount++;	
}														// -   !!!

void startTransmitter (uint32_t baudRate, uint32_t timeSend) {
//    !!!
uint16_t ubrr = 0;
if (baudRate == 115200) ubrr = 8;
else ubrr = 16000000/16/baudRate-1;
//    !!!
UBRRnH = (unsigned char)(ubrr>>8);
UBRRnL = (unsigned char)ubrr;
//  
SetBit(UCSRnB, TXEN0);
//  
SetBit(UCSRnB, RXEN0);
//       
SetBit(UCSRnB, RXCIE0);
//    8 data 1 stop bit
SetBit(UCSRnC, 1);
SetBit(UCSRnC, 2);
// 
Serial34bSendTimeOUT = timeSend;
OCR0A = 0xA0;			//  
SetBit(TIMSK0, OCIE0A);	//  
//   PIN 13
LedPinOut();
//  
for (uint8_t i = 0; i <= 26; i++) transm_arr[i] = 0;
for (uint8_t i = 0; i <= 26; i++) receiv_arr[i] = 0;
}
Serial27bReceiver.hArduino
#include "Arduino.h"
#include "UartAndPinConfig.h"

const uint8_t transmStart = 129;  	//   
const uint8_t transmEnd = 130;	  	//   

const uint8_t receiverStart =254; 	//   	 
const uint8_t receiverEnd = 255;  	//   

//       
volatile uint32_t Serial34bSendTimeOUT;
//    		
volatile uint32_t Serial34bTimeCore = 0;
//    -  
volatile boolean transmTOUT = true;
//    
volatile uint8_t BYTEinCount = 0;
//   
volatile uint8_t inUart_arr[32];
//    
volatile uint8_t rErrTime = 0;
//    
volatile uint8_t rErrCRC = 0;  


ISR (TIMER0_COMPA_vect) {
Serial34bTimeCore ++;
if (Serial34bTimeCore >	Serial34bSendTimeOUT) {		//   
Serial34bTimeCore = 0;								//  
LedPinOFF();										//   -  
rErrTime ++;										//    												
}				
}

ISR (BYTEin) {										//    
	
	uint8_t	dat = 0;								//     !!!
	dat = UDRn;

if (receiverStart == dat){							//     
	BYTEinCount = 0;
	//   inUart_arr[32]
	for (uint8_t i = 0; i <= 31; i++) inUart_arr[i] = 0;
	return;
	}

if (receiverEnd == dat){
													
	//   
	uint8_t b8_arr[28];
	//   
	for (uint8_t i = 0; i <= 27; i++) b8_arr[i] = 0;
	
	//  	
	uint8_t k = 0;
	uint8_t q = 1;		
	for (uint8_t j = 0; j <= 27; j=j+7) { // 0, 7, 14, 31
		
	for (uint8_t i = j; i <= j+6; i++) {   // 0...6 / 7...13 /14...20 / 21...27 /
		b8_arr[i] = inUart_arr[k];
		b8_arr[i] <<= (7+j-i);
		b8_arr[i] &= B10000000;
		b8_arr[i] |= inUart_arr[i+q];	
	}									   // 0...6 / 7...13 /14...20 / 21...27 /			   
	k = k + 8;
	q = q + 1;  
  }										   // 0, 7, 14, 31										   
	//  

	//  
	uint16_t crc16 = 0;
	for (int i = 1; i <= 27; i++) crc16 = crc16 + b8_arr[i] * 44111;
	uint8_t crc8 = 0;
	crc8 = crc16 & 255;	
	//  
	if (b8_arr[0] == crc8) {
	//    !!!  
	for (int i = 0; i <=26; i++) transm_arr[i] = b8_arr[i+1];
	//  
	LedPinOn();
	//   
	Serial34bTimeCore = 0;	
	} else {
	//  
	LedPinOFF();
	//     
	rErrCRC++;
	}
		
	//    receiv_arr [27] !!!!	
	
	//       UART
	uint8_t uart_arr[32];
	for (uint8_t i = 0; i <= 31; i++) uart_arr[i]=0;

	//    b8_arr[28];
	b8_arr[0] = 0;
	//      
	for (uint8_t i = 1; i <= 27; i++) b8_arr[i] = receiv_arr[i-1];
	
	//         
	int8_t uartCount = 0;
	for (uartCount = 27; uartCount >= 0; uartCount--) {
    if (b8_arr[uartCount] != 0) break; 		//   uartCount 
	}
	
	if (uartCount != -1) { 		//    -     
	// 
	//           
	crc16 = 0;	
	crc8 = 0;
	for (uint8_t i = 1; i <= uartCount; i++) crc16 = crc16 + b8_arr[i] * 44111;
	crc8 = crc16 & 255;	
	b8_arr[0] = crc8;

	//  8-    7- 

	k = 0;
	q = 1; 		
	for (uint8_t j = 0; j <= 24; j=j+8) { // 0, 8, 16, 24  
	for (uint8_t i = k; i <= k+6; i++) { // 0...6 / 7...13 /14...20 / 21...27 / 
	uart_arr[i+q] = b8_arr[i];
	uart_arr[i+q] &= B01111111;
	b8_arr[i]     &= B10000000;
	uart_arr[j] |= b8_arr[i];
	uart_arr[j] >>= 1;
	} 									 // 0...6 / 7...13 /14...20 / 21...27 /  
	if (uartCount<j) break;	    //    
	uartCount ++;  
	k = k + 7; 
	q = q + 1;
   }								 	// 0, 8, 16, 24      
}	//        UART uart_arr[32] 
	
	//    
	while ( !( UCSRnA & (1<<UDRE0)) );
	UDRn = transmStart;
	//  uart_arr[32]		
	for (int8_t i = 0; i <= uartCount; i++) {
	while ( !( UCSRnA & (1<<UDRE0)) );
	UDRn = uart_arr[i];
	}	
	//    
	while ( !( UCSRnA & (1<<UDRE0)) );
	UDRn = transmEnd;				
		
	return;	
}
	//      
	inUart_arr[BYTEinCount] = dat;
    BYTEinCount++;
	
} 											//    



void startReceiver (uint32_t baudRate, uint32_t timeSend) {
//    !!!
uint16_t ubrr = 0;
if (baudRate == 115200) ubrr = 8;
else ubrr = 16000000/16/baudRate-1;
//    !!!
UBRRnH = (unsigned char)(ubrr>>8);
UBRRnL = (unsigned char)ubrr;
//  
SetBit(UCSRnB, TXEN0);
//  
SetBit(UCSRnB, RXEN0);
//       
SetBit(UCSRnB, RXCIE0);
//    8 data 1 stop bit
SetBit(UCSRnC, 1);
SetBit(UCSRnC, 2);
// 
Serial34bSendTimeOUT = timeSend;
OCR0A = 0xA0;			//  
SetBit(TIMSK0, OCIE0A);	//  
//   PIN 13
LedPinOut();
//  
for (uint8_t i = 0; i <= 26; i++) transm_arr[i] = 0;
for (uint8_t i = 0; i <= 26; i++) receiv_arr[i] = 0; 
}
rc_submarine_transmitter_v2.inoArduino
//     I2C
#include <Wire.h>
//     
#include <Adafruit_INA219.h>
//     
Adafruit_INA219 ina219;

#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

//    UART
#define Serial_2

byte transm_arr[27];  //     
byte receiv_arr[27];  //     

//   
#include <Serial27bTransmitter.h>

boolean backL = 0;  //  enable fix
boolean backR = 0;  //  enable fix
boolean frontL = 0; //  enable fix
boolean frontR = 0; //  enable fix

boolean RL3 = 0; // RL3 ~  
boolean LL3 = 0; // LL3 ~  
boolean RL2 = 0; // RL2 ~ airPump 
boolean LL2 = 0; // LL2 ~ airPump 

boolean RL3y = 0; // RL3 ~  
boolean LL3y = 0; // LL3 ~  
boolean RL2y = 0; // RL2 ~ airPump 
boolean LL2y = 0; // LL2 ~ airPump 

boolean key4 = 0; // KEY BC547B LED-LIGHT

boolean fixEnaB = 0; //    
boolean fixEnaS = 0; //    

void setup() {
  //  ,   ()
  startTransmitter(9600, 200);

  pinMode(42, INPUT_PULLUP); //  
  pinMode(36, INPUT_PULLUP); // 1 ULN2803 (1-2) enable
  pinMode(37, INPUT_PULLUP); // 1 ULN2803 (3-4) enable
  pinMode(38, INPUT_PULLUP); // 1 ULN2803 (5-6) enable
  pinMode(39, INPUT_PULLUP); // 1 ULN2803 (7-8) enable

  pinMode(40, INPUT_PULLUP); // autodiving
  pinMode(25, INPUT_PULLUP); // autodiving cancel

  pinMode(29, INPUT_PULLUP); // QE4 2 ULN2803 (1-2) // 
  pinMode(30, INPUT_PULLUP); // QG6 2 ULN2803 (5-6) // 
  pinMode(22, INPUT_PULLUP); // QF5 2 ULN2803 (3-4) // 
  pinMode(23, INPUT_PULLUP); // QH7 2 ULN2803 (7-8) // 

  pinMode(41, INPUT_PULLUP); // enable Fix Motor button

  lcd.begin(20, 4);

  //   
  ina219.begin();

  //   RX/TX  
  pinMode(14, OUTPUT);   digitalWrite(14, 1);
  pinMode(15, OUTPUT);   digitalWrite(15, 1);
  pinMode(18, OUTPUT);   digitalWrite(18, 1);
  pinMode(19, OUTPUT);   digitalWrite(19, 1);
}

void loop() {

  //     
  if (digitalRead(41))   fixEnaB = false;
  if (!digitalRead(41) && !fixEnaB) {
    fixEnaS = !fixEnaS;
    fixEnaB = true;
  }

  //   fix
  if (digitalRead(42))   key4 = false;
  if (!digitalRead(42) && !key4) {
    bitWrite(transm_arr[0], 0, !bitRead(transm_arr[0], 0));
    key4 = true;
  }
  // bitWrite(transm_arr[0], 0, !digitalRead(42)); no fix

  // autodiving 
  if (!digitalRead(40)) {
  bitWrite(transm_arr[0], 1, !digitalRead(40)); // no fix
  transm_arr[5] = map(analogRead(A12), 0, 1023, 0, 255); 
  } else {
  bitWrite(transm_arr[0], 1, 0);
  transm_arr[5] = 0;  
  }
  // autodiving cancel
  bitWrite(transm_arr[0], 2, !digitalRead(25)); // no fix
    
  if (digitalRead(36))   RL3 = false;
  if (!digitalRead(36) && !RL3) {
    RL3y = !RL3y;
    RL3 = true;
  }
  //bitWrite(transm_arr[0], 4, !digitalRead(36)); nofix

  if (digitalRead(37))   LL3 = false;
  if (!digitalRead(37) && !LL3) {
    LL3y = !LL3y;
    LL3 = true;
  }
  //bitWrite(transm_arr[0], 5, !digitalRead(37)); nofix

  if (digitalRead(38))   RL2 = false;
  if (!digitalRead(38) && !RL2) {
    RL2y = !RL2y;
    RL2 = true;
  }
  // bitWrite(transm_arr[0], 6, !digitalRead(38)); nofix

  if (digitalRead(39))   LL2 = false;
  if (!digitalRead(39) && !LL2) {
    LL2y = !LL2y;
    LL2 = true;
  }

  //         
  if (RL3y) transm_arr[1] = map(analogRead(A8), 0, 1023, 0, 255); else  transm_arr[1] = 0; // RL3 ~  
  if (LL3y) transm_arr[2] = map(analogRead(A9), 0, 1023, 0, 255); else  transm_arr[2] = 0; // LL3 ~  
  if (RL2y) transm_arr[3] = map(analogRead(A10), 0, 1023, 0, 255); else transm_arr[3] = 0; // RL2 ~ airPump 
  if (LL2y) transm_arr[4] = map(analogRead(A11), 0, 1023, 0, 255); else transm_arr[4] = 0; // LL2 ~ airPump 

  //  L293D    pwm
  uint16_t leftRES = analogRead(A14);
  uint16_t righRES = analogRead(A15);

  //   EN2
  uint8_t pwmL;

  if (leftRES >= 563) {
    // 
    pwmL = map(analogRead(A14), 563, 1023, 0, 127);
    bitWrite(pwmL,7,1);
  } else if (leftRES <= 460) {
    // 
    pwmL = map(analogRead(A14), 460, 0, 0, 127);
  } else {
    // 
    pwmL = 0;
  }

  //   EN1
  uint8_t pwmR;
  if (righRES >= 563) {
    // 
    pwmR = map(analogRead(A15), 563, 1023, 0, 127);
    bitWrite(pwmR,7,1);    
  } else if (righRES <= 460) {
    // 
    pwmR = map(analogRead(A15), 460, 0, 0, 127);
  } else {
    // 
    pwmR = 0;
  }
  //    
  transm_arr[6] = pwmL;
  transm_arr[7] = pwmR;
  
  //     PWM     
  if (fixEnaS) {

    // 
    if (digitalRead(30))   backL = false;
    if (!digitalRead(30) && !backL) {
      bitWrite(transm_arr[0], 4, !bitRead(transm_arr[0], 4));
      backL = true;
    }

    // 
    if (digitalRead(23))   backR = false;
    if (!digitalRead(23) && !backR) {
      bitWrite(transm_arr[0], 5, !bitRead(transm_arr[0], 5));
      backR = true;
    }

    // 
    if (digitalRead(29))   frontL = false;
    if (!digitalRead(29) && !frontL) {
      bitWrite(transm_arr[0], 6, !bitRead(transm_arr[0], 6));
      frontL = true;
    }

    // 
    if (digitalRead(22))   frontR = false;
    if (!digitalRead(22) && !frontR) {
      bitWrite(transm_arr[0], 7, !bitRead(transm_arr[0], 7));
      frontR = true;
    }
  } else {
    bitWrite(transm_arr[0], 4, !digitalRead(30));
    bitWrite(transm_arr[0], 5, !digitalRead(23));
    bitWrite(transm_arr[0], 6, !digitalRead(29));
    bitWrite(transm_arr[0], 7, !digitalRead(22));
  }


  //   
  lcd.clear();

  lcd.setCursor(0, 0);
  lcd.print(transm_arr[1]);
  lcd.setCursor(0, 1);
  lcd.print(transm_arr[2]);
  lcd.setCursor(0, 2);
  lcd.print(transm_arr[3]);
  lcd.setCursor(0, 3);
  lcd.print(transm_arr[4]);

  lcd.setCursor(4, 0);
  lcd.print('-');
  lcd.print(pwmL);

  lcd.setCursor(4, 1);
  lcd.print('-');
  lcd.print(pwmR);
  
  lcd.setCursor(4, 2);
  lcd.print("d-");
  lcd.print(bitRead(transm_arr[0], 1));  
  
  lcd.setCursor(4, 3);
  lcd.print(map(analogRead(A12), 0, 1023, 0, 255));

  //  c pwm
  lcd.setCursor(9, 0);
  lcd.print(RL3y);
  lcd.setCursor(9, 1);
  lcd.print(LL3y);
  lcd.setCursor(9, 2);
  lcd.print(RL2y);
  lcd.setCursor(9, 3);
  lcd.print(LL2y);

  //   pwm
  lcd.setCursor(18, 0);
  lcd.print(bitRead(transm_arr[0], 6));
  lcd.print(bitRead(transm_arr[0], 7));
  lcd.setCursor(18, 1);
  lcd.print(bitRead(transm_arr[0], 4));
  lcd.print(bitRead(transm_arr[0], 5));

  //  
  lcd.setCursor(15, 2);
  lcd.print("rV");
  float ShowV = receiv_arr[0];
  ShowV = ShowV / 10;
  lcd.print(ShowV, 1);

  //   
  float busvoltage = 0;
  //    GND  V-
  busvoltage = ina219.getBusVoltage_V();
  lcd.setCursor(15, 3);
  lcd.print("tV");
  lcd.print(busvoltage, 1);

  //    
  lcd.setCursor(15, 0);
  lcd.print(fixEnaS);
  lcd.print(bitRead(transm_arr[0], 0));

  delay(100);
}

/*
   
  0 
  Bit0 KEY BC547B LED-LIGHT  // 42 
  1  74HC595
  QA0
  QB1
  QC2
  QD3
  QE4 2 ULN2803 (1-2)
  QF5 2 ULN2803 (3-4)
  QG6 2 ULN2803 (5-6)
  QH7 2 ULN2803 (7-8)

*/
rc_submarine_receiver_v2.inoArduino
//     I2C
#include <Wire.h>
//     
#include <Adafruit_INA219.h>
//     
Adafruit_INA219 ina219;
/*----------------------------------------------------*/

#define LL1 8
#define RL1 7
#define LL2 6 //~
#define RL2 5 //~
#define LL4 4
#define LL3 3 //~
#define RL3 2 //~
#define RL4 21
#define LED 20
#define LMrev 16
#define LMpwm 9  //~
#define RMrev 17
#define RMpwm 10 //~

//    UART (    )
#define Serial_0

byte transm_arr[27];  //     
byte receiv_arr[27];  //    

//   
#include <Serial27bReceiver.h>

long previousMillis = 0;
long interval = 0;


void setup() {
  //   ,      ()
  startReceiver(9600, 400);
  //   
  ina219.begin();
  pinMode(LED, OUTPUT); // KEY BC547B LED-LIGHT
  pinMode(LL1, OUTPUT);  // LL1  BLesft
  pinMode(RL1, OUTPUT);  // RL1  RRight
  pinMode(LL2, OUTPUT);  // LL2 ~ airPump 
  pinMode(RL2, OUTPUT);  // RL2 ~ airPump 
  pinMode(LL4, OUTPUT);  // LL4  FLesft
  pinMode(LL3, OUTPUT);  // LL3 ~  
  pinMode(RL3, OUTPUT);  // RL3 ~  
  pinMode(RL4, OUTPUT);  // RL4  FRight
  pinMode(LMrev, OUTPUT);  //   
  pinMode(LMpwm, OUTPUT);  //   
  pinMode(RMrev, OUTPUT);  //    
  pinMode(RMpwm, OUTPUT);  //   
}

void loop() {
  
  // 
  digitalWrite(LED, bitRead(transm_arr[0], 0));
  // 
  digitalWrite(LL1, bitRead(transm_arr[0], 4));
  digitalWrite(RL1, bitRead(transm_arr[0], 5));
  digitalWrite(LL4, bitRead(transm_arr[0], 6));
  digitalWrite(RL4, bitRead(transm_arr[0], 7));
  //    
  analogWrite(RL3, transm_arr[1]); // RL3 ~  
  analogWrite(LL3, transm_arr[2]); // LL3 ~  
  analogWrite(RL2, transm_arr[3]); // RL2 ~ airPump  
  analogWrite(LL2, transm_arr[4]); // LL2 ~ airPump 
  //  ,       
  digitalWrite(LMrev, bitRead(transm_arr[6], 7));   //    
  digitalWrite(RMrev, bitRead(transm_arr[7], 7));   //      
  uint8_t SpeedLM = transm_arr[6];
  uint8_t SpeedRM = transm_arr[7];   
  bitClear(SpeedLM, 7);
  bitClear(SpeedRM, 7);  
  analogWrite(LMpwm, map(SpeedLM, 0, 127, 0, 255));
  analogWrite(RMpwm, map(SpeedRM, 0, 127, 0, 255)); 
  //   !!!
  //   INA219
  float busvoltage = 0;
  //    GND  V-
  busvoltage = ina219.getBusVoltage_V() * 10;
  busvoltage = round(busvoltage);
  //    
  receiv_arr[0] = busvoltage;
  if (digitalRead(13) == LOW) {
    if (rErrTime > 1) {
    transm_arr[0] = 1;
    transm_arr[1] = 0;
    transm_arr[2] = 0;
    transm_arr[3] = 0;
    transm_arr[4] = 0;
    transm_arr[6] = 0;
    transm_arr[7] = 0;
    }
  } else rErrTime =0;
  // autodiving 
  if (bitRead(transm_arr[0],1)) {
  interval = transm_arr[5] * 1000;
  analogWrite(RL3, 255); // RL3 ~  
  analogWrite(LL3, 255); // LL3 ~  
  analogWrite(RL2, 255); // RL2 ~ airPump  
  analogWrite(LL2, 255); // LL2 ~ airPump 
  autodiving_label:
  unsigned long currentMillis = millis(); 
  //     ,   
  if(currentMillis - previousMillis > interval) {
    //    
    previousMillis = currentMillis;        
  }  else {
  //      
  if (bitRead(transm_arr[0],2)) interval=0;
  goto autodiving_label;
  }
  }  
  delay(100);
}

Schematics

rc submarine circuit diagram
Circuit diagram lsfzskyumg

Comments

Similar projects you might like

Turn your RC Car to Bluetooth RC car

Project tutorial by Prajjwal Nag

  • 23,402 views
  • 3 comments
  • 27 respects

RC LOGGERSTATION - GPS Data Logger for RC Plane

Project tutorial by yvesmorele

  • 2,649 views
  • 1 comment
  • 8 respects

Quick RC Robot controlled by iOS app

Project showcase by Georges Giroux

  • 10,790 views
  • 5 comments
  • 22 respects

RC Car Over Spektrum Remote

Project showcase by Gkid19

  • 1,955 views
  • 0 comments
  • 4 respects

Renewing the Nikko Turbo 2 RC Car

Project tutorial by MarcoGPS

  • 4,229 views
  • 2 comments
  • 10 respects

Making Arduino-Based RC Transmitter of USB Flight Simulator

Project showcase by tsar_

  • 3,922 views
  • 2 comments
  • 9 respects
Add projectSign up / Login