I recently tried to make a menu on 128x64 oled display I2C and arduino uno so I found this really good tutorial(https://youtu.be/HVHVkKt-ldc). I wrote code to make menu scroll using joystick than I added a little game, uploaded code to my arduino and it worked well. I played that game on arduino and after three days display started randomly freezing only way to fix that eas to reset the arduino but when i played game it never freezed, display was only freezing when I was scrolling through the menu. By the way I was using u8glib. If you have any questions I'll respond as quickly as possible. Please hel me to solve this problem.
I tried everything: I rewrote logic, I replaced joystick with buttons, I uploaded different programs i just don't know what to do.
here is my code, sorry that it is messy.
#include <U8glib.h>
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST); // Fast I2C / TWI
const int NUM_ITEMS = 5;
// 'icon 1', 16x16px
const unsigned char epd_bitmap_icon_1 [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x77, 0x77,
0x7f, 0xff, 0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// 'icon 2', 16x16px
const unsigned char epd_bitmap_icon_2 [] PROGMEM = {
0x00, 0x00, 0x01, 0x80, 0x02, 0x40, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xc0, 0x02, 0x40, 0x02, 0xc0,
0x02, 0x40, 0x02, 0xc0, 0x02, 0x40, 0x04, 0x20, 0x06, 0x20, 0x07, 0xe0, 0x03, 0xc0, 0x00, 0x00
};
// 'icon 3', 16x16px
const unsigned char epd_bitmap_icon_3 [] PROGMEM = {
0x00, 0x00, 0x14, 0x00, 0x08, 0x00, 0x11, 0x00, 0x01, 0x0a, 0x01, 0x04, 0x01, 0x0a, 0x01, 0x00,
0x01, 0xf8, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char epd_bitmap_icon_4 [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x06,
0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char epd_bitmap_icon_5 [] PROGMEM = {
0x1f, 0xf8, 0x1f, 0xf8, 0x10, 0x08, 0x10, 0x08, 0x13, 0xc8, 0x09, 0x90, 0x04, 0x20, 0x02, 0x40,
0x02, 0x40, 0x05, 0xa0, 0x08, 0x10, 0x11, 0x88, 0x11, 0xc8, 0x13, 0xc8, 0x1f, 0xf8, 0x1f, 0xf8
};
const unsigned char epd_bitmap_frame [] PROGMEM = {
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0
};
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 144)
void setup(void) {
u8g.setColorIndex(1);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(13, INPUT_PULLUP);
Serial.begin(9600);
}
const unsigned char* icons[NUM_ITEMS] = {
epd_bitmap_icon_1,
epd_bitmap_icon_2,
epd_bitmap_icon_3,
epd_bitmap_icon_4,
epd_bitmap_icon_5
};
char menu_items [NUM_ITEMS] [20] = {
{"Distance meter"},
{"Thermometer"},
{"Gyro"},
{"Game"},
{"Timer"}
};
int previous_it;
int selected_it = 0;
int next_it;
int xStick;
int yStick;
unsigned long sec;
char location = "menu";
byte btnC = 0;
boolean btn;
int x_cir = 32;
int y_cir = 64;
void stickValues(){
xStick = analogRead(A0);
yStick = analogRead(A1);
yStick = map(yStick, 0, 1023, -1, 6);
constrain(yStick, -1, 6);
xStick = map(xStick, 0, 1023, -1, 6);
constrain(xStick, -1, 6);
btn = !digitalRead(13);
}
void circle(){
u8g.drawLine(20, 32, 30, 32);
u8g.drawLine(59, 10, 69, 10);
u8g.drawLine(98, 32, 108, 32);
u8g.drawCircle(y_cir, x_cir, 4);
}
void game(){
stickValues();
if (millis() - sec > 50){
if(yStick < 2 && y_cir < 128){
y_cir += 4;
}
if(yStick > 4 && y_cir > 0){
y_cir -= 4;
}
if(xStick < 2 && x_cir > 0){
x_cir -= 4;
}
if(xStick > 4 && x_cir < 64){
x_cir += 4;
}
sec = millis();
}
}
void loop(void){
// logic to select item
stickValues();
if(btnC != 1){
if(xStick < 2 && millis() - sec > 200){
selected_it += 1;
if(selected_it == 4){selected_it = 0;}
sec = millis();
}
if(xStick > 4 && millis() - sec > 200){
selected_it -= 1;
if(selected_it == -1){selected_it = 4;}
sec = millis();
}
}
previous_it = (selected_it - 1);
if (previous_it < 0) {previous_it = 4;} // previous item would be below first = make it the last
next_it = (selected_it + 1);
if (next_it > 4) {next_it = 0;}
// end
// actions to begin the game
if(selected_it == 3 && btnC == 1){
if (millis() - sec > 50){
if(btn == 1){
btnC++;
if(btnC > 1){btnC = 0;}
}
game();
sec = millis();
}
}
// end
//serial things
// Serial.print("btn ");
// Serial.print(btn);
// Serial.print(" btnC ");
// Serial.print(btnC);
// Serial.print(" yStick ");
// Serial.print(yStick);
// Serial.print(" xStick ");
// Serial.print(xStick);
// Serial.print(" selected_it ");
// Serial.print(selected_it);
// Serial.print(" next_it ");
// Serial.println(next_it);
// button counter
if(btn == 1){
btnC++;
if(btnC > 1){btnC = 0;}
}
//end
u8g.firstPage();
do {
// game begin
if(selected_it == 3 && btnC == 1){circle();}
//
// menu begin
if(btnC == 0 ){
//previos item
u8g.setFont(u8g_font_7x14);
u8g.drawStr(26, 15, menu_items[previous_it]);
u8g.drawBitmapP( 4, 2, 16/8, 16, icons[previous_it]);
//selected item
u8g.setFont(u8g_font_7x14B);
u8g.drawStr(26, 37, menu_items[selected_it]);
u8g.drawBitmapP( 4, 24, 16/8, 16, icons[selected_it]);
//next item
u8g.setFont(u8g_font_7x14);
u8g.drawStr(26, 59, menu_items[next_it]);
u8g.drawBitmapP( 4, 46, 16/8, 16, icons[next_it]);
u8g.drawBitmapP( 0, 22, 128/8, 20, epd_bitmap_frame);
}
// menu end
} while( u8g.nextPage() );
}
I have a problem with my esp8266 project. My purpose is to use esp8266 to transmit beacon frames every one second so that my android device or my laptop can receive it and display in list of APs which i can connect to.
Here is my code I wrote:
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
void setup() {
delay(500);
sendBeacon("ESP8266");
ESP.deepSleep(10e5);
}
void loop() {
}
void sendBeacon(char* ssid) {
// Randomize channel //
byte channel = 1;
wifi_set_channel(channel);
uint8_t packet[128] = { 0x80, 0x00, //Frame Control
0x00, 0x00, //Duration
/*4*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address
/*10*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
/*16*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
/*22*/ 0xc0, 0x6c, //Seq-ctl
//Frame body starts here
/*24*/ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
/*32*/ 0xFF, 0x00, //Beacon interval
/*34*/ 0x01, 0x04, //Capability info
/* SSID */
/*36*/ 0x00
};
int ssidLen = strlen(ssid);
packet[37] = ssidLen;
for(int i = 0; i < ssidLen; i++) {
packet[38+i] = ssid[i];
}
uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
for(int i = 0; i < 12; i++) {
packet[38 + ssidLen + i] = postSSID[i];
}
packet[50 + ssidLen] = channel;
// get SRC MAC
unsigned char mac[6];
WiFi.macAddress(mac);
packet[10] = packet[16] = mac[0];
packet[11] = packet[17] = mac[1];
packet[12] = packet[18] = mac[2];
packet[13] = packet[19] = mac[3];
packet[14] = packet[20] = mac[4];
packet[15] = packet[21] = mac[5];
int packetSize = 51 + ssidLen;
wifi_send_pkt_freedom(packet, packetSize, 0);
delay(1);
}
I used tcpdump to capture those frame and yes, they are there. But I still couldn't see it in list of AP on my laptop and my android device.
I can see it if I stop using deep sleep mode. For example:
#include <ESP8266WiFi.h>
extern "C" {
#include "user_interface.h"
}
void setup() {
delay(500);
// sendBeacon("ESP8266");
// ESP.deepSleep(10e5);
}
void loop() {
sendBeacon("ESP8266");
}
void sendBeacon(char* ssid) {
// Randomize channel //
byte channel = 1;
wifi_set_channel(channel);
uint8_t packet[128] = { 0x80, 0x00, //Frame Control
0x00, 0x00, //Duration
/*4*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //Destination address
/*10*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //Source address - overwritten later
/*16*/ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, //BSSID - overwritten to the same as the source address
/*22*/ 0xc0, 0x6c, //Seq-ctl
//Frame body starts here
/*24*/ 0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00, //timestamp - the number of microseconds the AP has been active
/*32*/ 0xFF, 0x00, //Beacon interval
/*34*/ 0x01, 0x04, //Capability info
/* SSID */
/*36*/ 0x00
};
int ssidLen = strlen(ssid);
packet[37] = ssidLen;
for(int i = 0; i < ssidLen; i++) {
packet[38+i] = ssid[i];
}
uint8_t postSSID[13] = {0x01, 0x08, 0x82, 0x84, 0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, //supported rate
0x03, 0x01, 0x04 /*DSSS (Current Channel)*/ };
for(int i = 0; i < 12; i++) {
packet[38 + ssidLen + i] = postSSID[i];
}
packet[50 + ssidLen] = channel;
// get SRC MAC
unsigned char mac[6];
WiFi.macAddress(mac);
packet[10] = packet[16] = mac[0];
packet[11] = packet[17] = mac[1];
packet[12] = packet[18] = mac[2];
packet[13] = packet[19] = mac[3];
packet[14] = packet[20] = mac[4];
packet[15] = packet[21] = mac[5];
int packetSize = 51 + ssidLen;
wifi_send_pkt_freedom(packet, packetSize, 0);
delay(1);
}
Does anyone know why? Please help me to get this, thanks!
First of all, ESP.deepSleep(10e5) makes the processor sleep for 100ms, not a second. The correct would be ESP.deepSleep(10e6). Secondly, you are trying to send just one packet every second or so, it's quite hard to make sure that the wifi reading from the device is gonna get that packet for sure and display it on the list of SSIDs. From my experiments, I had to send three packets every 200ms to make sure it was displayed on my android mobile and pc. You can try to play with the number of packets you send and the interval to see what fits you best...
Also, make sure to configure the ESP correctly at the setup function. When I tried my similar code I had to use two instructions: wifi_set_opmode(STATION_MODE) and wifi_promiscuous_enable(1)
Could you pls help me in this type of task.Actually I dont understand what I should provide as an answer
A given bit vector has length n. It is known that the vector can contain only two ones. A combinational system needs to calculate the distance between the ones. For example, in vector "10100" the distance is 2. Give the high-level specification.
When google turned up this SO question for me, I was pretty excited. I was hoping there'd be some code here I could repurpose. Alas, the OP's question was too abstract for a concrete solution to get proposed.
Still, for the next guy, here's at least /a/ solution, designed for MSVC x64:
#include <intrin.h> // __lzcnt64 & _BitScanForward64
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
/// <summary>
/// Given a pointer to an array of bits, prints out the distance between the bits.
/// </summary>
/// <param name="pBits">Pointer to the bits</param>
/// <param name="len">Length of the array in bytes</param>
/// <param name="carry">Previous value of carry</param>
/// <returns>Final carry</returns>
/// <remarks>Reading right to left, a bit pattern of 11100101 (aka 0xE5) will print 1, 2, 3, 1, 1</remarks>
uint64_t CountBitDistance(const uint8_t* pBits, const size_t len, uint64_t carry = 0)
{
// Assumes len divides evenly by 8. Depending on the platform,
// pBits might also need to be 8 byte aligned. Left as an exercise.
assert((len % 8) == 0);
const uint64_t* pUll = (const uint64_t*)pBits;
for (size_t x = 0; x < len / 8; pUll++, x++)
{
uint64_t ull = *pUll;
// Grab the value before we start modifying ull
const uint64_t newcarry = __lzcnt64(ull);
unsigned long res = 0;
// Returns false when ull is zero. res is zero based.
while (_BitScanForward64(&res, ull))
{
// Tempting though it might be, you can't just increment res and
// do both shifts at once. If the only bit set is the most
// significant one, adding 1 gives you 64. Shifting a 64bit value
// by 64 is undefined behavior in C. On x64 for example, it does
// nothing. If you are *sure* that res will never be 63, or if
// you are on a platform that handles shifts > 63 differently (and
// don't need a portable solution), you could combine them and
// increase perf (by a tiny amount).
// So, first get rid of the zeros...
ull >>= res;
// ... then turn off the bit we just found.
ull >>= 1;
// If we found a bit at position 0, we want to report 1.
res++;
// And apply any carry in from the previous ull.
const uint64_t d = carry + res;
// Carry in applied.
carry = 0;
printf("%llu\n", d);
}
// Remember that we might not go into the loop above at all, so carry
// won't necessarily be zero.
carry += newcarry;
}
// Useful if the source of our bits is continuing to produce data. We may
// need the final value from the previous batch to apply to the next.
return carry;
}
int main()
{
constexpr const uint8_t bits[] = {
0xAA, 0x25, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x42, 0x10, 0x08, 0x08, 0x10, 0x40, 0x00,
0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xAA, 0x25, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0x25, 0x42, 0x10, 0x08, 0x08, 0x10, 0x40, 0x00,
};
constexpr const uint8_t bits2[] = { 0x2, 0, 0, 0, 0, 0, 0, 0 };
uint64_t t1 = CountBitDistance(bits, sizeof(bits));
printf("t1: %llu\n\n", t1);
uint64_t t2 = CountBitDistance(bits2, sizeof(bits2), t1);
printf("t2: %llu\n", t2);
}
No doubt someone else will pop up with a drastically better solution using some clever bit twiddling hacks. Still, at least now there's something.