Sunday, December 25, 2016

Mini Portable Temp/Humidity Sensor (ESP01 + DHT22 + LiPo Battery)

I like making sensors, I have a few projects at any given time dealing with some sort of sensors. I finished one today, enough to call it done for now that is. It uses a basic DHT22 sensor with an ESP01 wifi module. You can also use a DHT11 but the 22's cost a little more and offer better accuracy.

There are plenty of tutroials out there on how to do this. The sort of unique thing for mine is I wanted the data put in to an ElasticSearch instance I run. I'm all about sensors and storing info, and ElasticSearch has been great for that. So since I already have an ELK setup running for things like my Geiger Counter, Nest Thermostat, and Weather Underground data, I figured having my own little temp/humidity modules adding data would be a great spot.

The problem with most tutorials out there is that they focused on creating a webpage you go to, or posting data to some website that offers IOT services. So my version 1 of this included just making the ESP have a basic webpage with the available temperature and humidity information on it. It would just constantly loop checking the sensor and providing the connection. That wasn't ideal as that involves me to visit the webpage either manually or with a script. So I used a script for a while and it worked fine, but I still wanted them to be standalone objects where I didn't need to have static IP's for them or modify the script everytime I added or removed one.

So version 2 I sat down and finally figured out how to have the ESP module post data to a Logstash instance and get it imported in to Elasticsearch. Turns out it was pretty easy to do.


First the Hardware. This is the working version and it's compact. Not the prettiest but it works fine. Here's what's inside it and some rough prices.


  • ESP01 module - $2
  • DHT22 sensor module - $3
  • TP4056 LiPo Charger - $1.20
  • 100 mAh LiPo battery - $4
  • Micro USB prt on the TP4056 and a Male USB port added for power as well $0.20
  • On/Off Switch $0.02
  • A Diode to drop the voltage just a little to the ESP $0.01
So about $11 per module. Cheaper if you just use a 3.3 volt regulator on a USB port to power it. But I wanted a battery to make it portable (put it where you want to measure something like a car or garage).







You can plug it in to Micro USB....

Or plug it in to one of the readily available USB plugs and let it be.



Here's a basic chart of the data the module POSTs to ELK. The temp is high because it's sitting on my computer tower running in battery only mode right now. I'm trying to see the run time on it, and I'll hopefully update the next sentance once I get a time.





And the data that's being collected each POST and stored.






And here's the code. The few parts you'd want to change are probably the Node name of the module, and your Logstash instance IP/Port.


#include
#include

const char* ssid     = "SSID Home";
const char* password = "P@ssword";

#define DHTPIN 2
#define DHTTYPE DHT22

DHT dht(DHTPIN, DHTTYPE);



void setup() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  pinMode(LED_BUILTIN, OUTPUT);
  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(100);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(100);
  }
  dht.begin();
}




void loop() {
  

  // Read humidity
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  WiFiClient client;

  String PostData = "{\"node\": \"LivingRoom\",\"humidity\": ";
  PostData += (float)h, 2;
  PostData += ",";
  PostData += "\"temp_c\": ";
  PostData += (float)t, 2;
  PostData += ",";
  PostData += "\"temp_f\": ";
  PostData += (float)f, 2;
  PostData += "}";


  const uint16_t port = 8080;
  const char* host = "192.168.1.18";

  if (client.connect(host, port)) {
    digitalWrite(LED_BUILTIN, LOW);
    client.println("POST /posts HTTP/1.1");
    client.println("Host: 192.168.1.18");
    client.println("Cache-Control: no-cache");
    client.println("Content-Type: application/json");
    client.print("Content-Length: ");
    client.println(PostData.length());
    client.println();
    client.println(PostData);
    client.stop();
    digitalWrite(LED_BUILTIN, HIGH);
  }

  delay(60000);

  
}






Friday, December 23, 2016

ESP8266 - Create tons of SSID's...with style

First off, the inspiration and most of the credit comes from this blog post. It gave me an idea to create a module that has some extended capabilities. So I set to work. And spoiler, I made it and it works fine.

Random SSID AP's are neat but the esp can do a lot more (more than I know how to do I'm sure). So I decided to add some features. Since there are 2 GPIO's and two states, I could come up with 4 variations in the actions of that script. So before building or coding anything, I decided what I wanted it to do (without knowing if it was even possible).


  • Mimic Mode - This would scan local access points and spoof them.
  • Static Mode - This would be a single static SSID that would be blasted out.
  • List Mode - This would be a similar to static, but from a preset list it loops through.
  • Random Mode - essentially the same thing as the blog post that inspired this.
First things first. I'm not that good with arduino and this is my first esp8266 project. But there are a lot of examples and truthfully, I'm pretty good a copy/pasting other peoples code and getting it to work how I want. So the code probably isn't the best and definitely isn't pretty. The only coding language I know is bash, so if anything it's probably written in more of a scripting way.

Here's the kicker from the original blog post. That's cool that one esp can do all those fake esp's, but what about more. What about.....8 :). What about.....16 :). Well that's what I decided to do. The module has 8-16 available sockets when plugged in. Here's a picture real quick so you know what it looks like as I continue to talk about it.


A few notes:
  • The LED display at the top is a pre-bought voltage meter. These are great and cheap (get them on eBay). Since the ESP modules are sensitive to voltage, I added one. 
  • Three slide switches.
    • Upper right - Power
    • Lower ones connect to the two GPIO pins and set the Mode of operation listed above
  • USB pcb plug bolted on
  • Right above the USB plug is a buck converter set to drop the 5 volts USB down to about 3.8 volts for the ESP modules
  • All of the sockets for the ESP's (2x4's) are all connected in parallel, which sucked to solder.


I said up to 16, why are there only 8 modules? Well, power. I used this with a USB power bank that is rated to provide up to 2.4 amps. That amperage is able to power 8 of them steadily, but not 16. That dips the voltage too much and most of the modules end up not starting up. So here's what I did. The back PCB plate with the other 8 sockets is removable. I did this by using 4 brass standoffs to separate the PCB's. With 4 posts, I could provide positive power, negative power, and the two GPIO pin settings. Just pinch the wire between the posts and it makes it easy to add the second board with sockets or remove it and have a blank board as a back. Bam, easy.



About the Code. 
The hardest thing to program was the Mimic Mode. This one scans for local access points to mimic. Scan, store, reproduce. But just mimicking isn't good enough. The SSID's need to be slightly different. This is because the exact same SSID's will normally jsut be grouped together. So I came up with a simple way to avoid this from happening for the host machines. Just add spaces. So here's what I did. When broadcasting any of the SSID's, every loop adds a space to teh SSID until it hits the max SSID length. So guest wifi will be guest wifi , guest wifi  , guest wifi   , guest wifi    , etc. Easy for a computer to tell the difference but near impossible to tell for a human. 

The GPIO settings. So the ESP (to start up properly) needs the gpio pins set to HIGH to start properly. Opposite from most things Arduino, OFF is HIGH and ON is LOW essentially. If the ESP starts with the GPIO pins LOW, it won't start at all and will end up in flash mode or something else. So in the VOID SETUP section, the modules wait 5 seconds after power on for the GPIO pins to be set, then reads them. One they are read, it sets the parameters for whatever mode is selected. 

The relevant code about the Mode selection (the delays were for some watchdog issues that may have been unrelated...):


  if (switchGPIO0 == HIGH && switchGPIO2 == HIGH)
  {
    mimicMode = true;
    scan = true;
    delay(1);
  }
  else if (switchGPIO0 == LOW && switchGPIO2 == HIGH)
  {
    randomMode = true;
    delay(1);
  }
  else if (switchGPIO0 == HIGH && switchGPIO2 == LOW)
  {
    listMode = true;
    delay(1);
  }
  else //(switchGPIO0 == LOW && switchGPIO2 == LOW)
  {
    staticMode = true;
    delay(1);
  }


So by having each pin in a given on/off position, you have 4 modes it can be configured to do. Since mimic mode is the coolest mode, and the pin defaults are HIGH, that's the defaulkt mode if no switches are toggled.

Really that's pretty much it. It can broadcast a crap ton of stuff. It's hard to measure since it overloads most wifi modules I've checked. Like a built in wifi card in a netbook and an external Alfa adapter I checked. Seems that when there' sover 255 AP's available, stuff starts having problems.

Here's a quick video of it in Mimic Mode. There are 5 flashes to set the mode, and then 3 more in Mimic Mode to let all the ESP's finish their scan. The once any broadcasting in any more starts, it flashes the built in Blue LED on and off for each loop. It sends a lot out since it looks steady once started.



And the current code (it ain't pretty) in Arduino IDE. I'm sure it can be better but for a silly project, I'm calling it done:


#include

extern "C" {
#include "user_interface.h"
}


byte channel;
int wifiCount = 0;
int fullPacket;
int switchGPIO0;
int switchGPIO2;
String wifissid;

bool promiscuousMode = false;

bool mimicMode = false;
bool scan = false;

bool randomMode = false;
int randomStart;

bool listMode = false;
char* networkList[] = {"attwifi", "HomeNetwork", "Starbucks", "guest", "ATT_8765", "Beaches", "Seagulls" };


bool staticMode = false;
String staticNet = "¯\\_(ツ)_/¯";





void setup() {
  delay(1);
  WiFi.mode(WIFI_STA);
  // Initialize the LED_BUILTIN pin as an output
  pinMode(LED_BUILTIN, OUTPUT);

  // Initialize the GPIO pins as inputs
  pinMode(0, INPUT);
  pinMode(2, INPUT);
  // Wait 5 seconds to set switches
  for (int i = 0; i < 5; ++i)
  {
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(500);
  }

  // Check the GPIO config set up and determine the operation mode being used
  switchGPIO0 = digitalRead(0);
  switchGPIO2 = digitalRead(2);
  delay(1);

  if (switchGPIO0 == HIGH && switchGPIO2 == HIGH)
  {
    mimicMode = true;
    scan = true;
    delay(1);
  }
  else if (switchGPIO0 == LOW && switchGPIO2 == HIGH)
  {
    randomMode = true;
    delay(1);
  }
  else if (switchGPIO0 == HIGH && switchGPIO2 == LOW)
  {
    listMode = true;
    delay(1);
  }
  else //(switchGPIO0 == LOW && switchGPIO2 == LOW)
  {
    staticMode = true;
    delay(1);
  }


}







void loop() {

  // Write blue LED HIGH (off)
  digitalWrite(LED_BUILTIN, HIGH);

  // Do an initial scan to find available network names
  if (scan == true)
  {
    wifiCount = WiFi.scanNetworks();
    // Make sure this doesn't run again now that the scan is done
    scan = false;
    // Wait 3 seconds for the other modules before starting
    for (int i = 0; i < 3; ++i)
    {
      digitalWrite(LED_BUILTIN, LOW);
      delay(500);
      digitalWrite(LED_BUILTIN, HIGH);
      delay(500);
    }
  }
  else if (randomMode == true)
  {
    wifiCount = 50;
    // So after 50 loops below, pick a new random number
    randomStart = random(23560);
  }
  else if (listMode == true)
  {
    wifiCount = 6;

  }
  else if (staticMode == true)
  {
    wifiCount = 1;
  }




  if (promiscuousMode == false)
  {
    promiscuousMode = true;
    wifi_set_opmode(STATION_MODE);
    wifi_promiscuous_enable(1);
  }


  delay(1);




  // Start looping through SSID's
  for (int i = 0; i < wifiCount; ++i)
  {
    // Get the SSID to use this round (increasing array value changes SSID)
    if (mimicMode == true)
    {
      // Pick a random SSID
      //int wifiCountArray = wifiCount - 1;
      wifissid = WiFi.SSID(random(wifiCount));
    }
    else if (randomMode == true)
    {
      // Just start at the picked random number and add 1 each loop
      int randVal = randomStart + 1;
      wifissid = String(randVal);
    }
    else if (listMode == true)
    {
      wifissid = networkList[i];
    }
    else
    {
      wifissid = staticNet;
    }



    // Beacon Packet buffer ( this resets the variable every loop. weird things happened when it was global... )
    uint8_t packet[128] = { 0x80, 0x00, 0x00, 0x00,
                            /*4*/   0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                            /*10*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
                            /*16*/  0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
                            /*22*/  0xc0, 0x6c,
                            /*24*/  0x83, 0x51, 0xf7, 0x8f, 0x0f, 0x00, 0x00, 0x00,
                            /*32*/  0x64, 0x00,
                            /*34*/  0x01, 0x04,
                            /* SSID */
                            /*36*/  0x00, 0x01, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
                            /*71*/  0x01, 0x08, 0x82, 0x84,
                            /*75*/  0x8b, 0x96, 0x24, 0x30, 0x48, 0x6c, 0x03, 0x01,
                            /*83*/  0x05, 0x20
                          };


    // Get the SSID length to modify that length value in the beacon
    int wifiLength = wifissid.length();
    // Array spot to start printing SSID
    int ssidSpot = 38;
    // If the SSID is too long, cut it
    if (wifiLength > 30)
    {
      wifiLength = 30;
    }


    // Start printing the SSID in to the packet array at the start spot stated above
    for (int i = 0; i < wifiLength; ++i)
    {
      packet[ssidSpot] = wifissid[i];
      ++ssidSpot;
    }

    // BROADCAST LOOP. Start with 1 space added to SSID and continue until 30 characters long
    for (int j = wifiLength; j < 30; ++j)
    {
      // Kill the "add a space each iteration" looping here if you want



      // Add a space right after the SSID that was printed above
      packet[ssidSpot] = packet[84];
      // Print the now complete SSID length right before the SSID start spot in packet
      packet[37] = j + 1;



      // Move to the next array spot after the last space was added
      ++ssidSpot;

      // Pick a channel to use
      channel = random(1, 12);
      wifi_set_channel(channel);

      // Change the last array value in the "ending" part of the SSID beacon to the channel being used
      packet[83] = channel;
      // Just copying the left off ssid spot for the second part of the packet to start
      int packetPartTwo = ssidSpot;

      // Print the complete second packet portion in to the complete packet array now that the SSID is printed in
      for (int m = 71; m < 84; ++m)
      {
        packet[packetPartTwo] = packet[m];
        ++packetPartTwo;
      }

      // Random MAC address
      packet[10] = packet[16] = random(256);
      packet[11] = packet[17] = random(256);
      packet[12] = packet[18] = random(256);
      packet[13] = packet[19] = random(256);
      packet[14] = packet[20] = random(256);
      packet[15] = packet[21] = random(256);

      // Broadcast the Beacons!
      fullPacket = packetPartTwo; // + 1;
      // Write blue LED LOW (on)
      digitalWrite(LED_BUILTIN, LOW);
      wifi_send_pkt_freedom(packet, fullPacket, 0);
      wifi_send_pkt_freedom(packet, fullPacket, 0);
      wifi_send_pkt_freedom(packet, fullPacket, 0);


      // Write blue LED HIGH (off)
      digitalWrite(LED_BUILTIN, HIGH);

      delay(10);
    }
    delay(10);
  }
  delay(10);
}










Wednesday, November 2, 2016

Cisco AA20270 Power Supply

So I have some old crappy Cisco routers. Cpecifically I'm working with a Cisco 2610. It's a junk router these days, so I have other plans for it.




Anyways, I wanted to use the built in power supply for my project and not provide an external one. Turns out, it's similar to ATX power supplies where it won't turn on unless you do a little dance. For an ATX power supply, there is a well documented PWR_ON pin to tap to ground. And voila, power. For this power supply, no documentation I could find.

So with a little bit of poking and testing, I found out it's super easy. I checked the pins on the router board itself and noticed that the +5v and GND had continuity. So I pulled out a high wattage resistor (to hopefully not blow something up if I was wrong) and connected them. Ta-da. That's how you turn on a Cisco AA20270 Power Supply. Now I have 12v and 5v supplies to use.



So... it's pretty obvious with this power supply to tell when it isn't "on". It has an audible clicking at about 3.5Hz and you don't get a constant power. Th clicking is essentially the power supply checking if it can enable fullpower or not.


Simply tap that GRD to a +5v pin, and you're good though. Here's the clicking sound and showing you get constant voltage once you connect +5v to GND.


EDIT: I think It just needs some sort of current going rather than just connecting wires. The connecting wires actually carry a current through them so you can't just do a basic connection like with an ATX power supply. Use a high watt resistor or an actual load.


Wednesday, September 21, 2016

IR floodlights off of Landscape Lighting

So I bought a Dahua POE PTZ camera off eBay. Great camera and I'm happy with it, but it has no built in IR lights. That's a problem at night. It has much better IR sensitivity than my Hikvisions, but just not good enough.

Installing an IR flood light is easy to do. Just buy one off eBay and plug it in. But I didn't want to run extra wires and I didn't want to take up another outlet (or use a powerstrip) in my garage.

I already have some landscape lighting installed with a way overpowered power box running them since I installed LED lights recently. So I set out to run my IR floodlights off of my lanscape lighting.

This proved to be not challenging at all. You just need the right parts.


  • Infrared LED flood lights
  • Full bridge rectifier (best to get one with a heatsink)
  • A standard lanscape lighting tap
  • Various plugs and wires


The rectifier I got is a 50 amp 1000 volt one with a heatsink off of eBay for $2 with free shipping. I already happened to have some plugs that fit the terminals on it.


The lanscape lighting tap is meant to run another similar landscape cable to another part of the path/area. Or to actually tap in a light. It uses sharp prings to dig in to the cable you are connecting to, and the new cable. These work well and provide a reasonably water proofed connection. Available at pretty much anywhere that sells landscape lighting (got mine at Lowes).


So forst install a short wire to the new tap part on the tap. I used speaker wire since I didn't have any more lanscape wire to use. Then added terminals.


Then you just hook up the terminals from the tap to the AC sides of the rectifier. And hook up your cable going to the IR lights to the positive and negative sides (be sure to check and verify this before installing).


This is a temporary place to put this set up while I work on maybe designing a 3D printed enclosure for it all.


Now I can power 2 LED IR floodlights for my camera using my already installed landscape lighting that runs on 12 volts AC.

Sunday, September 4, 2016

Rope Cutter

I was looking at getting some paracord, maybe only 10 feet or so. Just because I kept needing small amounts of rope when twine simply wouldn't cut it. Well it turns out it's way more cost effective to buy in bulk for paracord. So instead or 10 or 20 feet, I bought 1000 feet in a spool.



So now I had a bulky spool of rope to manage every time I wanted to cut some length. So my solution was to mount it somewhere, and have a cutting tool readily available. The problem was, I lose tools a lot. So I needed a mounted cutting tool. So off to the 3D printer. I designed a small little tool that mounts to my wooden shelves right next to the paracord spool. So now I can just pull a length and cut it real quick.



I thought ahead a little about the blade to use. Since there are two common blades relatively the same side, I designed it to accept both blades in the cutter.





So you just loop it through the hole, loop around the notches (to get tension on the rope) and then a quick wiggle against the blade to cut it. Here's the 3D stl file.






Saturday, September 3, 2016

Arduino Sensor Pod - Mock up

I got all my parts in from eBay finally (well except a 3 volt regulator pack they had to reship). So I soldered up some headers on to a mock up of the layout. I think I may put in the effort and cash to get some custom pcb's for this project. Mainly because this will be a lot of wiring if I don't and a real mess to troubleshoot if there's an issue. I like having the header pins though, makes it easy to swap out parts and move things around.






Lighting Saber

No not a light saber, a lighting saber. I needed a light above my computer desk that gave decent, broad light for when I work on projects and take pictures. So I decided to use my 3 monitor set up to my advantage. Essentially it's just a light bar that has a dimmer and is moveable.




Materials needed:
PWM dimmer (generic one that can be found all ober the place)
LED light strip (also all over the place)
8 M3 16mm bolt/nuts
A drill
3d Printed part from HERE
1/4 inch slotted aluminum bar (says for plywood)
A 12 volt power supply


So the hardest part for this is probably getting a good 3D print and mounting those parts. All you do is print them, drill some holes, and put in the bolts like so.



After that, mount the PWM dimmer and the light stip to the bottom of the aluminum bar. The length can be easily cut to size. You may want to add additional glue to the ends and the middle to prevent the double sided tape it comes with from releasing.



Then just plug in the wires and wave around your saber. Or lean it somewhere or whatever. You get some good light now.




Sunday, August 21, 2016

Dewalt 14.4 Volt Teardown

When I first bought my dewalt drill, I got a great deal in my opinion. I got the drill, charger, case, bit set, and 2 batteries for $100. That was about 3 years ago. Well, one of the batteries finally dies on me. So I decided to take it apart and take a look before trashing it.


So here's the battery. Lightly used over the past few years I'd say. I noticed it didn't hold much of a charge and marked the bottom with a piece of tape since it was going bad. One day it finally held no charge at all.


Here's the bottom and model number DW9094.


Once you remove a few torx screws on the top, you're in.


The battery pack is what I expected. A bunch of single cells in series to get to the 14.4 volts needed. The top and bottom of the pack had some cardboard and tape to keep it together as more of a structure.

Once the cardboard is removed, you can see the series hookup for the batteries.


I clipped all of the connections and tested each cell for voltage. I expected maybe a few dead cells and some with a few bits of charge left since it hadn't been that long since I last tried to charge it. But all of the betteries registed no voltage. In a way that makes ssense since this was a series hookup though. If one cell died completely, that would break the circuit and no cells would be getting a charge.



So I decided to keep the cells since it'sl likely some may still be good. Though honestly, probably not good enough to do anything with. The battery case though, that may have some use. I may look in to putting some lithium cells with safety ciruitry in it. There's a lot of space in there to try and use.


Sunday, August 14, 2016

3D Printed Rope Cutter

I bought 1000 feet of parachute cord and wanted a built in cutter where I mounted it. So I designed a quick tool in TinkerCad. I had two blade to choose from to use, a standard box cutting blade and a flat scraping blade. Turns out they are close in size so I just made it so you could use wither blade.

Here's a Thingiverse link to it.









Two screws to mount and it's done. Just pull the rope through, wrap it around the bottom prong and guide it in to the blade slot. This allows you to put tension on the line and cut it with a quick swipe or two.

Wednesday, August 10, 2016

Remote IR Signals



I'm looking in to possibly reverse engineering remotes so I can reproduce signals with an Arduino. It would be pretty cool to do this in an automated fashion but that may be a lot more work than it's worth. Plus I need to look in to getting an IR receiver. Anyways, having an Oscilloscope is nice to see these types of things.

"UP" Arrow Key
"DOWN" Arrow Key
A Difference In Frequencies Between The Screenshots



Thursday, July 28, 2016

2016 Altima SR Inside Fuse Layout

Just because this may be helpful to someone. Here's the inside fuse layout for a 2016 Altima SR 2.5L.


Thursday, July 14, 2016

3D Gnuplot Gif

I needed to make a rotating graph in gnuplot. The plot itself was a 3d plot with one axis being time, one being a server name, and one being a mail count. The graph was fine and all but due to using the heat surface look, it was hard to see some things in the back of the graph. So I wanted to make a gif that simply rotated it.


I did some research and this ended up seeming nigh impossible to do within gnuplot alone. I was able to plot the graph how I wanted by controlling the viewpoint. So I figured if there is a way I can make a ton of output png files, I could use those to create a gif. Turns out this method works quite well. And the best part is that it can all be automated with a script needing no human interaction. The only downside is if you want a small gif at the end, you need to resize/resample it. The final gif I use is a rofling 30 megs. It's 360 frames at a full 1400 by 700 a frame. But on an internal network, this is perfectly fine. You can adjust resolution of the individual graphs in the gnuplot config file.




#! /bin/bash

# Script for creating a gif from the gnuplot pics.

# You need this for fonts: sudo apt-get -y install libgd2-xpm-dev build-essential

#This was for starting out without any residual files

rm /var/www/Servers/test/*.png /var/www/Servers/test/*animation*gif


# All the counters and such initiated

count=0

rotation=0

gifnum=0

gifchunk=0

fullcount=0



while [ $fullcount -lt 360 ] # Main loop; 360 degrees for a perfect spin gif

do



# 'convert' is used to make the gif and it uses globbing

# more than 10 pics at a time will mean they get out of order

while [ $count -lt 10 ]

do


# see the gnuplot config file below


# These sed statemnts are adjusting the output picture number and angle per rep through the 10 count 'while' statement

sed s/XNUMX/$count/ /var/www/Servers/test/3dgnuplot.cfg > /var/www/Servers/test/3dgnuplot.cfg.tmp

sed -i s/XVIEWX/$rotation/ /var/www/Servers/test/3dgnuplot.cfg.tmp


# mmake 1 graph

gnuplot /var/www/Servers/test/3dgnuplot.cfg.tmp



# increment the while10 count, full count (up to 360) and rotation degree (last two interchangable really)

count=$(echo $(($count + 1)))

rotation=$(echo $(($rotation + 1)))

fullcount=$(echo $(($fullcount + 1)))

done


# so after making 10 pictures, use convert to make a gif, keeping it at 10 means globbing works fine

# gifnum is just referencing the while10 gif number so I can glob those later

convert -delay 20 -loop 0 /var/www/Servers/test/*.png /var/www/Servers/test/$gifnum.animation.gif

# after making the gif, remove the png's

rm /var/www/Servers/test/*.png

# reset the while10 counter

count=0

# increment the gif counter

gifnum=$(echo $(($gifnum + 1)))



#####################################

# When you get 10 gifs that the while10 loop made, it globs them together for a larger gif

if [[ $gifnum -eq 9 ]]

then


convert -delay 20 -loop 0 /var/www/Servers/test/*animation.gif /var/www/Servers/test/animation.$gifchunk.gif

gifchunk=$(echo $(($gifchunk + 1)))

gifnum=0

rm /var/www/Servers/test/*.animation.gif

fi

#####################################


done

# After all is said and done and you get the 360 degrees (360 pics made),

# remove all gifs except your larger gif chunks you made

# then use convert to combine all your gifs together in to a mega gif

rm /var/www/Servers/test/*.animation.gif

convert -delay 10 -loop 0 /var/www/Servers/test/animation.* /var/www/Servers/test/myfinalform.gif

# myfinalform.gif is the finished product



## gnuplot config used; you can adjust these to adjust the final gnuplot form

#set term png

#set output '/var/www/Servers/test/XNUMXdgraph.png'

#set terminal png size 1400,700

#set title "Messages processed each hour"

#unset border

#unset surface

#set pm3d at bs

#set hidden3d

#set ylabel "Server"

#set xlabel "Time"

#set dgrid3d 100,100,2

#set samples 50

#set isosamples 50

#set view ,XVIEWX

#splot '/var/www/Servers/3dgnuplot.dat' using 2:1:4:xtic(2):ytic(3) title "Message Counts"







So it may seem like a lot but most of that code is purely to get globbing to work. Without it, you get a schizophrenic gif due to the normal ordering of files (1,12,2,22,3,37,etc). So here's a simple breakdown of what's going on.

Make 10 graphs at incrementing angles

Take those 10 graphs and make a gif

Rinse and repeat above

If you get 10 gifs, combine to larger gif

Once 360 pics are made in to 10-at-a-time gifs, combine all of those gifs in to the final product

Here's a trimmed down sample of it.


Wednesday, July 13, 2016

Ultrasonic Sensor on an Oscilloscope

So having an oscilloscope makes me always wonder how most electronics work and communicate data. I unfortunately am no expert but sometimes a scope can really help you better understand what's actually going on. In my testing of sensors for the sensor project, I was looking at the Ultrasonic sensors output. Really it's pretty straight forward.

The sensor puts out a pulse and listens back for the response. When that pulse is sent out, the output pin for the echo is set to HIGH. When the reflected ultrasonic sound comes back, the echo pin goes back down to LOW. So essentially all that an arduino does it measure the time between the high and low rise and fall, then calculate the distance based on the speed of sound.

Here was a short video of me moving back and forth in front of a sensor showing the incresing and decresing pulse length.


Zip File Header Chart

I work with looking at zip files a lot. There's a lot of very specific and useful information in a zip header that many don't realize. I frequently needed this information and it's a lot to memorize down to the specifics. So I made a somewhat useful chart. This allows me to be able to open a zip and quickly look at some of the specific hex values and know what they are referencing at a glance. My chart making skills aren't the best, but it works for me.