Hướng dẫn làm led cube 4x4x4 arduino

/* 4x4x4 LED Cube Connection Setup: Columns [(x,y)-Pin] (1,1)-13 (1,2)-12 (1,3)-11 (1,4)-10 (2,1)-9 (2,2)-8 (2,3)-7 (2,4)-6 (3,1)-5 (3-2)-4 (3-3)-3 (3,4)-2 (4,1)-1 (4,2)-0 (4,3)-A5 (4,4)-A4 Layers [layer-Pin] a-A0 b-A1 c-A2 d-A3 */ //initializing and declaring led rows int column[16]={13,12,11,10,9,8,7,6,5,4,3,2,1,0,A5,A4}; //initializing and declaring led layers int layer[4]={A3,A2,A1,A0}; int time = 250; void setup() { //setting rows to ouput for(int i = 0; i<16; i++) { pinMode(column[i], OUTPUT); } //setting layers to output for(int i = 0; i<4; i++) { pinMode(layer[i], OUTPUT); } //seeding random for random pattern randomSeed(analogRead(10)); } //xxxxxxxxxxxxxxxxxxxxFUNCTION LOOPxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx void loop() { turnEverythingOff();//turn all off flickerOn(); turnEverythingOn();//turn all on delay(time); turnOnAndOffAllByLayerUpAndDownNotTimed(); layerstompUpAndDown(); turnOnAndOffAllByColumnSideways(); delay(time); aroundEdgeDown(); turnEverythingOff(); randomflicker(); randomRain(); diagonalRectangle(); goThroughAllLedsOneAtATime(); propeller(); spiralInAndOut(); flickerOff(); turnEverythingOff(); delay(2000); } //xxxxxxxxxxxxxxxxxxxxFUNCTIONSxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx //xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ///////////////////////////////////////////////////////////turn all off void turnEverythingOff() { for(int i = 0; i<16; i++) { digitalWrite(column[i], 1); } for(int i = 0; i<4; i++) { digitalWrite(layer[i], 0); } } ////////////////////////////////////////////////////////////turn all on void turnEverythingOn() { for(int i = 0; i<16; i++) { digitalWrite(column[i], 0); } //turning on layers for(int i = 0; i<4; i++) { digitalWrite(layer[i], 1); } } ///////////////////////////////////////////////////////turn columns off void turnColumnsOff() { for(int i = 0; i<16; i++) { digitalWrite(column[i], 1); } } /////////////////////////////////////////////////////////////flicker on void flickerOn() { int i = 150; while(i != 0) { turnEverythingOn(); delay(i); turnEverythingOff(); delay(i); i-= 5; } } //////////////turn everything on and off by layer up and down NOT TIMED void turnOnAndOffAllByLayerUpAndDownNotTimed() { int x = 75; for(int i = 5; i != 0; i--) { turnEverythingOn(); for(int i = 4; i!=0; i--) { digitalWrite(layer[i-1], 0); delay(x); } for(int i = 0; i<4; i++) { digitalWrite(layer[i], 1); delay(x); } for(int i = 0; i<4; i++) { digitalWrite(layer[i], 0); delay(x); } for(int i = 4; i!=0; i--) { digitalWrite(layer[i-1], 1); delay(x); } } } //////////////////////////turn everything on and off by column sideways void turnOnAndOffAllByColumnSideways() { int x = 75; turnEverythingOff(); //turn on layers for(int i = 0; i<4; i++) { digitalWrite(layer[i], 1); } for(int y = 0; y<3; y++) { //turn on 0-3 for(int i = 0; i<4; i++) { digitalWrite(column[i], 0); delay(x); } //turn on 4-7 for(int i = 4; i<8; i++) { digitalWrite(column[i], 0); delay(x); } //turn on 8-11 for(int i = 8; i<12; i++) { digitalWrite(column[i], 0); delay(x); } //turn on 12-15 for(int i = 12; i<16; i++) { digitalWrite(column[i], 0); delay(x); } //turn off 0-3 for(int i = 0; i<4; i++) { digitalWrite(column[i], 1); delay(x); } //turn off 4-7 for(int i = 4; i<8; i++) { digitalWrite(column[i], 1); delay(x); } //turn off 8-11 for(int i = 8; i<12; i++) { digitalWrite(column[i], 1); delay(x); } //turn off 12-15 for(int i = 12; i<16; i++) { digitalWrite(column[i], 1); delay(x); } //turn on 12-15 for(int i = 12; i<16; i++) { digitalWrite(column[i], 0); delay(x); } //turn on 8-11 for(int i = 8; i<12; i++) { digitalWrite(column[i], 0); delay(x); } //turn on 4-7 for(int i = 4; i<8; i++) { digitalWrite(column[i], 0); delay(x); } //turn on 0-3 for(int i = 0; i<4; i++) { digitalWrite(column[i], 0); delay(x); } //turn off 12-15 for(int i = 12; i<16; i++) { digitalWrite(column[i], 1); delay(x); } //turn off 8-11 for(int i = 8; i<12; i++) { digitalWrite(column[i], 1); delay(x); } //turn off 4-7 for(int i = 4; i<8; i++) { digitalWrite(column[i], 1); delay(x); } //turn off 0-3 for(int i = 0; i<4; i++) { digitalWrite(column[i], 1); delay(x); } } } /////////////////////////////////////////up and down single layer stomp void layerstompUpAndDown() { int x = 75; for(int i = 0; i<4; i++) { digitalWrite(layer[i], 0); } for(int y = 0; y<5; y++) { for(int count = 0; count<1; count++) { for(int i = 0; i<4; i++) { digitalWrite(layer[i], 1); delay(x); digitalWrite(layer[i], 0); } for(int i = 4; i !=0; i--) { digitalWrite(layer[i-1], 1); delay(x); digitalWrite(layer[i-1], 0); } } for(int i = 0; i<4; i++) { digitalWrite(layer[i], 1); delay(x); } for(int i = 4; i!=0; i--) { digitalWrite(layer[i-1], 0); delay(x); } } } ////////////////////////////////////////////////////////////flicker off void flickerOff() { turnEverythingOn(); for(int i = 0; i!= 150; i+=5) { turnEverythingOff(); delay(i+50); turnEverythingOn(); delay(i); } } ///////////////////////////////////////////around edge of the cube down void aroundEdgeDown() { for(int x = 200; x != 0; x -=50) { turnEverythingOff(); for(int i = 4; i != 0; i--) { digitalWrite(layer[i-1], 1); digitalWrite(column[5], 0); digitalWrite(column[6], 0); digitalWrite(column[9], 0); digitalWrite(column[10], 0); digitalWrite(column[0], 0); delay(x); digitalWrite(column[0], 1); digitalWrite(column[4], 0); delay(x); digitalWrite(column[4], 1); digitalWrite(column[8], 0); delay(x); digitalWrite(column[8], 1); digitalWrite(column[12], 0); delay(x); digitalWrite(column[12], 1); digitalWrite(column[13], 0); delay(x); digitalWrite(column[13], 1); digitalWrite(column[15], 0); delay(x); digitalWrite(column[15], 1); digitalWrite(column[14], 0); delay(x); digitalWrite(column[14], 1); digitalWrite(column[11], 0); delay(x); digitalWrite(column[11], 1); digitalWrite(column[7], 0); delay(x); digitalWrite(column[7], 1); digitalWrite(column[3], 0); delay(x); digitalWrite(column[3], 1); digitalWrite(column[2], 0); delay(x); digitalWrite(column[2], 1); digitalWrite(column[1], 0); delay(x); digitalWrite(column[1], 1); } } } /////////////////////////////////////////////////////////random flicker void randomflicker() { turnEverythingOff(); int x = 10; for(int i = 0; i !=750; i+=2) { int randomLayer = random(0,4); int randomColumn = random(0,16); digitalWrite(layer[randomLayer], 1); digitalWrite(column[randomColumn], 0); delay(x); digitalWrite(layer[randomLayer], 0); digitalWrite(column[randomColumn], 1); delay(x); } } ////////////////////////////////////////////////////////////random rain void randomRain() { turnEverythingOff(); int x = 100; for(int i = 0; i!=60; i+=2) { int randomColumn = random(0,16); digitalWrite(column[randomColumn], 0); digitalWrite(layer[0], 1); delay(x+50); digitalWrite(layer[0], 0); digitalWrite(layer[1], 1); delay(x); digitalWrite(layer[1], 0); digitalWrite(layer[2], 1); delay(x); digitalWrite(layer[2], 0); digitalWrite(layer[3], 1); delay(x+50); digitalWrite(layer[3], 0); digitalWrite(column[randomColumn], 1); } } /////////////////////////////////////////////////////diagonal rectangle void diagonalRectangle() { int x = 350; turnEverythingOff(); for(int count = 0; count<5; count++) { //top left for(int i = 0; i<8; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[3], 1); digitalWrite(layer[2], 1); delay(x); turnEverythingOff(); //middle middle for(int i = 4; i<12; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[1], 1); digitalWrite(layer[2], 1); delay(x); turnEverythingOff(); //bottom right for(int i = 8; i<16; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[0], 1); digitalWrite(layer[1], 1); delay(x); turnEverythingOff(); //bottom middle for(int i = 4; i<12; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[0], 1); digitalWrite(layer[1], 1); delay(x); turnEverythingOff(); //bottom left for(int i = 0; i<8; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[0], 1); digitalWrite(layer[1], 1); delay(x); turnEverythingOff(); //middle middle for(int i = 4; i<12; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[1], 1); digitalWrite(layer[2], 1); delay(x); turnEverythingOff(); //top right for(int i = 8; i<16; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[2], 1); digitalWrite(layer[3], 1); delay(x); turnEverythingOff(); //top middle for(int i = 4; i<12; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[2], 1); digitalWrite(layer[3], 1); delay(x); turnEverythingOff(); } //top left for(int i = 0; i<8; i++) { digitalWrite(column[i], 0); } digitalWrite(layer[3], 1); digitalWrite(layer[2], 1); delay(x); turnEverythingOff(); } //////////////////////////////////////////////////////////////propeller void propeller() { turnEverythingOff(); int x = 90; for(int y = 4; y>0; y--) { for(int i = 0; i<6; i++) { //turn on layer digitalWrite(layer[y-1], 1); //a1 turnColumnsOff(); digitalWrite(column[0], 0); digitalWrite(column[5], 0); digitalWrite(column[10], 0); digitalWrite(column[15], 0); delay(x); //b1 turnColumnsOff(); digitalWrite(column[4], 0); digitalWrite(column[5], 0); digitalWrite(column[10], 0); digitalWrite(column[11], 0); delay(x); //c1 turnColumnsOff(); digitalWrite(column[6], 0); digitalWrite(column[7], 0); digitalWrite(column[8], 0); digitalWrite(column[9], 0); delay(x); //d1 turnColumnsOff(); digitalWrite(column[3], 0); digitalWrite(column[6], 0); digitalWrite(column[9], 0); digitalWrite(column[12], 0); delay(x); //d2 turnColumnsOff(); digitalWrite(column[2], 0); digitalWrite(column[6], 0); digitalWrite(column[9], 0); digitalWrite(column[13], 0); delay(x); //d3 turnColumnsOff(); digitalWrite(column[1], 0); digitalWrite(column[5], 0); digitalWrite(column[10], 0); digitalWrite(column[14], 0); delay(x); } } //d4 turnColumnsOff(); digitalWrite(column[0], 0); digitalWrite(column[5], 0); digitalWrite(column[10], 0); digitalWrite(column[15], 0); delay(x); } //////////////////////////////////////////////////////spiral in and out void spiralInAndOut() { turnEverythingOn(); int x = 60; for(int i = 0; i<6; i++) { //spiral in clockwise digitalWrite(column[0], 1); delay(x); digitalWrite(column[1], 1); delay(x); digitalWrite(column[2], 1); delay(x); digitalWrite(column[3], 1); delay(x); digitalWrite(column[7], 1); delay(x); digitalWrite(column[11], 1); delay(x); digitalWrite(column[15], 1); delay(x); digitalWrite(column[14], 1); delay(x); digitalWrite(column[13], 1); delay(x); digitalWrite(column[12], 1); delay(x); digitalWrite(column[8], 1); delay(x); digitalWrite(column[4], 1); delay(x); digitalWrite(column[5], 1); delay(x); digitalWrite(column[6], 1); delay(x); digitalWrite(column[10], 1); delay(x); digitalWrite(column[9], 1); delay(x); ///////////////////////////////////////spiral out counter clockwise digitalWrite(column[9], 0); delay(x); digitalWrite(column[10], 0); delay(x); digitalWrite(column[6], 0); delay(x); digitalWrite(column[5], 0); delay(x); digitalWrite(column[4], 0); delay(x); digitalWrite(column[8], 0); delay(x); digitalWrite(column[12], 0); delay(x); digitalWrite(column[13], 0); delay(x); digitalWrite(column[14], 0); delay(x); digitalWrite(column[15], 0); delay(x); digitalWrite(column[11], 0); delay(x); digitalWrite(column[7], 0); delay(x); digitalWrite(column[3], 0); delay(x); digitalWrite(column[2], 0); delay(x); digitalWrite(column[1], 0); delay(x); digitalWrite(column[0], 0); delay(x); ///////////////////////////////////////spiral in counter clock wise digitalWrite(column[0], 1); delay(x); digitalWrite(column[4], 1); delay(x); digitalWrite(column[8], 1); delay(x); digitalWrite(column[12], 1); delay(x); digitalWrite(column[13], 1); delay(x); digitalWrite(column[14], 1); delay(x); digitalWrite(column[15], 1); delay(x); digitalWrite(column[11], 1); delay(x); digitalWrite(column[7], 1); delay(x); digitalWrite(column[3], 1); delay(x); digitalWrite(column[2], 1); delay(x); digitalWrite(column[1], 1); delay(x); digitalWrite(column[5], 1); delay(x); digitalWrite(column[9], 1); delay(x); digitalWrite(column[10], 1); delay(x); digitalWrite(column[6], 1); delay(x); //////////////////////////////////////////////spiral out clock wise digitalWrite(column[6], 0); delay(x); digitalWrite(column[10], 0); delay(x); digitalWrite(column[9], 0); delay(x); digitalWrite(column[5], 0); delay(x); digitalWrite(column[1], 0); delay(x); digitalWrite(column[2], 0); delay(x); digitalWrite(column[3], 0); delay(x); digitalWrite(column[7], 0); delay(x); digitalWrite(column[11], 0); delay(x); digitalWrite(column[15], 0); delay(x); digitalWrite(column[14], 0); delay(x); digitalWrite(column[13], 0); delay(x); digitalWrite(column[12], 0); delay(x); digitalWrite(column[8], 0); delay(x); digitalWrite(column[4], 0); delay(x); digitalWrite(column[0], 0); delay(x); } } //////////////////////////////////////go through all leds one at a time void goThroughAllLedsOneAtATime() { int x = 15; turnEverythingOff(); for(int y = 0; y<5; y++) { //0-3 for(int count = 4; count != 0; count--) { digitalWrite(layer[count-1], 1); for(int i = 0; i<4; i++) { digitalWrite(column[i], 0); delay(x); digitalWrite(column[i], 1); delay(x); } digitalWrite(layer[count-1], 0); } //4-7 for(int count = 0; count < 4; count++) { digitalWrite(layer[count], 1); for(int i = 4; i<8; i++) { digitalWrite(column[i], 0); delay(x); digitalWrite(column[i], 1); delay(x); } digitalWrite(layer[count], 0); } //8-11 for(int count = 4; count != 0; count--) { digitalWrite(layer[count-1], 1); for(int i = 8; i<12; i++) { digitalWrite(column[i], 0); delay(x); digitalWrite(column[i], 1); delay(x); } digitalWrite(layer[count-1], 0); } //12-15 for(int count = 0; count < 4; count++) { digitalWrite(layer[count], 1); for(int i = 12; i<16; i++) { digitalWrite(column[i], 0); delay(x); digitalWrite(column[i], 1); delay(x); } digitalWrite(layer[count], 0); } } }


Page 2

This guide will show you how to use two servos to create a pan-tilt control for the ESP32-CAM. The ESP32 Cam is a small camera that can be used to take pictures and videos.

The servo is used to pan and tilt the camera. This can be used to create a security camera, a robotic eye, or anything else you can think of. We will also show you how to use a web interface to control the camera.

THANKS, NEXTPCB

I would like to thank the Nextpcb for supporting me on every project. If you have a PCB project, please visit the Nextpcb website to get exciting discounts and coupons as follows:

Step 1: Required Material

Step 2: Assemble Tilt Kit With Servos Motor

This fully-assembled pan-tilt kit is an excellent way to give your project the greatest range of motion with two servos.

The pan-tilt can rotate around 180° from side to side and can tilt up and downwards near 150°. It also comes fully assembled with two Micro Servos (SG-90 type) included and a 38mm x 36mm space to mount a camera.

You can use any microcontroller. They are suitable for beginners who want to make things move and the pan-tilt is an effortless way to give whatever you are making both left, right, and up-down motions.

Servo motors have three wires with different colors:

Step 3: ESP32 Cam Module

The ESP32-CAM is a development board with a built-in camera. It is based on the ESP32 chip and can be used to take high-quality still images and video. The ESP32-CAM can be interfaced with a variety of sensors and peripherals to create a powerful camera system.

We ESP32-CAM development board to control two servos that act as a pan-tilt mechanism for a camera. We’ll first write the code to control the servos using the Arduino IDE,

For this project, we’ll be using the SG90 servos, which have a minimum pulse width of 500 microseconds and a maximum pulse width of 2500 microseconds, we’ll be using a range of 0 degrees to 180 degrees for each servo.

The servo motor is a type of electric motor that can be used to control the position of an object. Servo motors are often used in robotics applications to control the movement of a robotic arm or leg. Servo motors are also used in radio-controlled airplanes and cars to control the movement of the control surfaces.

Step 4: Wiring Diagram

The wiring diagram is very clear. You have to connect the servo motor pins with ESP32 pins as per the schematic diagram. The schematic diagram is shown above.

Connect all parts using the schematic. Use a piece of double-sided tape to attach the ESP32-CAM to the Pan/Tilt.

Step 5: ​Setting Up ESP32 Development Board

You can program the camera module using the Arduino IDE. After you have installed the development environment, you can open it to prepare you for using the camera module.

1. Start Arduino IDE and open the Preferences window.

2. Enter https://dl.espressif.com/dl/package_esp32_index. into the File>Preferences>Additional Boards Manager URLs field of the Arduino IDE. You can add multiple URLs, separating them with commas.

3. Close this window with the OK Button. Open Boards Manager from Tools > Board menu and select the correct ESP32 Cam board.

Step 6: Upload the Code

Download the code from here

#define DUMMY_SERVO1_PIN 12 //We need to create 2 dummy servos.
#define DUMMY_SERVO2_PIN 13 //So that ESP32Servo library does not interfere with pwm channel and timer used by esp32 camera.

#define PAN_PIN 14


#define TILT_PIN 15

Servo dummyServo1;


Servo dummyServo2;
Servo panServo;
Servo tiltServo;

//Camera related constants


#define PWDN_GPIO_NUM 32
#define RESET_GPIO_NUM -1
#define XCLK_GPIO_NUM 0
#define SIOD_GPIO_NUM 26
#define SIOC_GPIO_NUM 27
#define Y9_GPIO_NUM 35
#define Y8_GPIO_NUM 34
#define Y7_GPIO_NUM 39
#define Y6_GPIO_NUM 36
#define Y5_GPIO_NUM 21
#define Y4_GPIO_NUM 19
#define Y3_GPIO_NUM 18
#define Y2_GPIO_NUM 5
#define VSYNC_GPIO_NUM 25
#define HREF_GPIO_NUM 23
#define PCLK_GPIO_NUM 22

const char* ssid = "NowISeeYou";


const char* password = "12345678";

AsyncWebServer server(80);


AsyncWebSocket wsCamera("/Camera");
AsyncWebSocket wsServoInput("/ServoInput");
uint32_t cameraClientId = 0;

#define LIGHT_PIN 4


const int PWMLightChannel = 4;

const char* htmlHomePage PROGMEM = R"HTMLHOMEPAGE(
































Pan:



Tilt:



Light:








)HTMLHOMEPAGE";

void handleRoot(AsyncWebServerRequest *request)


{
request->send_P(200, "text/html", htmlHomePage);
}

void handleNotFound(AsyncWebServerRequest *request)


{
request->send(404, "text/plain", "File Not Found");
}

void onServoInputWebSocketEvent(AsyncWebSocket *server,


AsyncWebSocketClient *client,
AwsEventType type,
void *arg,
uint8_t *data,
size_t len)
{
switch (type)
{
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
panServo.write(90);
tiltServo.write(90);
ledcWrite(PWMLightChannel, 0);
break;
case WS_EVT_DATA:
AwsFrameInfo *info;
info = (AwsFrameInfo*)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT)
{
std::string myData = "";
myData.assign((char *)data, len);
Serial.printf("Key,Value = [%s]\n", myData.c_str());
std::istringstream ss(myData);
std::string key, value;
std::getline(ss, key, ',');
std::getline(ss, value, ',');
if ( value != "" )
{
int valueInt = atoi(value.c_str());
if (key == "Pan")
{
panServo.write(valueInt);
}
else if (key == "Tilt")
{
tiltServo.write(valueInt);
}
else if (key == "Light")
{
ledcWrite(PWMLightChannel, valueInt);
}
}
}
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
default:
break;
}
}

void onCameraWebSocketEvent(AsyncWebSocket *server,


AsyncWebSocketClient *client,
AwsEventType type,
void *arg,
uint8_t *data,
size_t len)
{
switch (type)
{
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
cameraClientId = client->id();
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
cameraClientId = 0;
break;
case WS_EVT_DATA:
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
default:
break;
}
}

void setupCamera()


{
camera_config_t config;
config.ledc_channel = LEDC_CHANNEL_0;
config.ledc_timer = LEDC_TIMER_0;
config.pin_d0 = Y2_GPIO_NUM;
config.pin_d1 = Y3_GPIO_NUM;
config.pin_d2 = Y4_GPIO_NUM;
config.pin_d3 = Y5_GPIO_NUM;
config.pin_d4 = Y6_GPIO_NUM;
config.pin_d5 = Y7_GPIO_NUM;
config.pin_d6 = Y8_GPIO_NUM;
config.pin_d7 = Y9_GPIO_NUM;
config.pin_xclk = XCLK_GPIO_NUM;
config.pin_pclk = PCLK_GPIO_NUM;
config.pin_vsync = VSYNC_GPIO_NUM;
config.pin_href = HREF_GPIO_NUM;
config.pin_sscb_sda = SIOD_GPIO_NUM;
config.pin_sscb_scl = SIOC_GPIO_NUM;
config.pin_pwdn = PWDN_GPIO_NUM;
config.pin_reset = RESET_GPIO_NUM;
config.xclk_freq_hz = 20000000;
config.pixel_format = PIXFORMAT_JPEG;

config.frame_size = FRAMESIZE_VGA;
config.jpeg_quality = 10;
config.fb_count = 1;

// camera init


esp_err_t err = esp_camera_init(&config);
if (err != ESP_OK)
{
Serial.printf("Camera init failed with error 0x%x", err);
return;
}

if (psramFound())


{
heap_caps_malloc_extmem_enable(20000);
Serial.printf("PSRAM initialized. malloc to take memory from psram above this size");
}
}

void sendCameraPicture()


{
if (cameraClientId == 0)
{
return;
}
unsigned long startTime1 = millis();
//capture a frame
camera_fb_t * fb = esp_camera_fb_get();
if (!fb)
{
Serial.println("Frame buffer could not be acquired");
return;
}

unsigned long startTime2 = millis();


wsCamera.binary(cameraClientId, fb->buf, fb->len);
esp_camera_fb_return(fb);

//Wait for message to be delivered
while (true)
{
AsyncWebSocketClient * clientPointer = wsCamera.client(cameraClientId);
if (!clientPointer || !(clientPointer->queueIsFull()))
{
break;
}
delay(1);
}

unsigned long startTime3 = millis();
Serial.printf("Time taken Total: %d|%d|%d\n",startTime3 - startTime1, startTime2 - startTime1, startTime3-startTime2 );
}

void setUpPinModes()


{
dummyServo1.attach(DUMMY_SERVO1_PIN);
dummyServo2.attach(DUMMY_SERVO2_PIN);
panServo.attach(PAN_PIN);
tiltServo.attach(TILT_PIN);

//Set up flash light


ledcSetup(PWMLightChannel, 1000, 8);
pinMode(LIGHT_PIN, OUTPUT);
ledcAttachPin(LIGHT_PIN, PWMLightChannel);
}

void setup(void)


{
setUpPinModes();
Serial.begin(115200);

WiFi.softAP(ssid, password);


IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);

server.on("/", HTTP_GET, handleRoot);


server.onNotFound(handleNotFound);

wsCamera.onEvent(onCameraWebSocketEvent);
server.addHandler(&wsCamera);

wsServoInput.onEvent(onServoInputWebSocketEvent);


server.addHandler(&wsServoInput);

server.begin();


Serial.println("HTTP server started");

setupCamera();


}

void loop()


{
wsCamera.cleanupClients();
wsServoInput.cleanupClients();
sendCameraPicture();
//Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
}

Step 7: Testing

Install the Camera Module Mount the cam module with pan-tilt

insert your SD card into the cam’s slot, push that little piece of rubber back in, power the camera up by sliding the switch on the rear, and find its unique IP camera web-server.

Now you will be able to see the live video on the Smartphone.

I am super happy with the final outcome of this little gadget. You may gift this little gadget to someone on any occasion

Be the First to Share


Page 3

The whole idea came to me during the early covid-19 days, when my whole family (2 parents, 3 kids) was forced to remain at home, and both parents desperately attempting to get some work done from home.

After being interrupted time after time during voice and video calls I thought to myself how handy it would have been if I had an electrical sign that can display my current status, whether I'm in a call, my video cam is active and so on (if you ever tried to work from your bedroom and had to signal your partner that its probably not a good time for changing shirt while standing behind you, you know what I'm talking about)

Well, I couldn't find any, neither I had any real Arduino experience back then, but I do have quite some C and embedded programming experience plus some knowledge in electronics.

So by the time we were having the second Covid lockdown, I had the parts available plus the extra time as there wasn't much else to do.

How does it work

The Arduino part is pretty simple, I used an Arduino nano cheap clone wired to a LED matrix. The Arduino software is capable of displaying two elements, representing the microphone and the speakers and adding an animation overlay to signal when they are in use. It is controlled from a host PC by a USB cable, using a made-up text based protocol that allow the host PC to detect the connection status and control the display status.

The host part is a simple WinForms application (written in c#) that polls the host PC microphone and speakers status and update the LED display accordingly.

Required hardware and pricing

  • Max7219 8x32 LED matrix - ~6$
  • A breadboard (optional) and some male-to-female wires

I uploaded an hebrew-speaking video which explains the use of the "On Air" sign.


Page 4

A long time ago, I made some basic electronic devices, like a fake LED alarm for a car, or a slave flash for photography.

Recently I wanted to explore the arduino world. So I ordered a kit. With it, I found many types of components.

The goal is to use them to create fun objects.

In this game, you must move the ball represented by a flashing led by tilting the board. You must be careful that the ball does not fall.