12/4/14

MSGEQ7 Graphic Equalizer/Spectrum Analyzer

I finally got back around to messing with the MSGEQ7 LED equalizer/analyzer. I had planned to set this up in the windows in front of the house for Xmas but I appear to be running out of time. 2014-12-02 18.51.06

I’ll have to add a fritzing for this post at some point but I’ll just throw my code up here for now that I used to get this working. I used a couple pots to control the LED strip brightness and color.
At some point I’m going to use RFID cards and a web app to change the colors and brightness. I thought it would be cool to use RFID cards by the Xmas tree color coded so anyone walking by can swipe a card and change the tree color.

Right now it’s just set up for mono but I’m working on making a stereo PCB with 2 MSGEQ7’s. I’ll add more to this including my pcb’s once I’m finished. You could of course just by a MSGEQ7 shield from Sparkfun.

 https://www.sparkfun.com/products/10306

Here are some videos of it in action.

/*
msgeq7 ws2812 led equalizer
*/
#include <Adafruit_NeoPixel.h>
//#include "WS2812_Definitions.h"       //add this if you want
 
#define LED_PIN         6       //pin for led strip
#define LED_COUNT       49  //# of leds in strip
#define LED_IN_BAND     7       //# of leds per band
#define STROBE_PIN      2       //Strobe pin for msgeq7
#define RESET_PIN       3       //Reset pin for msgeq7
#define ANLG_IN_PIN     A2      //analog input pin for msgeq7
#define BRIGHT_PIN      A1      //pin for brightness potentiometer
#define COLOR_PIN       A0      //pin for color potentiometer
 
//setup strip values
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, NEO_RGB + NEO_KHZ800);
 
/*call out pins for msgeq7*/
int analogPin = ANLG_IN_PIN;    //output pin to read bands for eq7
int strobePin = STROBE_PIN;     //strobe pin for eq7
int resetPin = RESET_PIN;               //reset pin for eq7
int bandValue[7];                               // to hold a2d values
int bandMap[7];                                 //hold mapped values for the band
long lightState[7][7];                  //multidim array to hold light color use later or struct for lights
 
 
/*color and brightness  */
int brightPin = BRIGHT_PIN;     //pot pin
int bright = 0;                                 //variable to store value for brightness
int brightVal = 0;                      //brightness value
 
int colorPin = COLOR_PIN;               //pot for color adj
int color = 0;                                  //variable to store the pot value for color
int colorMap = 0;                               //temp value to store mapped color value
long adjColor[8] = {0xFFFFFF, 0xFF1493, 0xFFFF00, 0x556B2F, 0x48D1CC, 0xFF6347, 0xFF4500, 0x008000};
long colorVal = 0;                              //value for color of led strip
int ledsInBand = LED_IN_BAND;   //leds in band, in defines
 
 
 
void setup()
{
  Serial.begin(9600);
  //Serial.print("\eSP F");  // tell to use 7-bit control codes
  //Serial.print("\e[?25l"); // hide cursor
  //Serial.print("\e[?12l"); // disable cursor highlighting
 
  strip.begin();        //      LED strip setup
  strip.show();         // Initialize all pixels to 'off'
 
  //initialize the msgeq7
  pinMode(analogPin, INPUT);
  pinMode(strobePin, OUTPUT);
  pinMode(resetPin, OUTPUT);
  analogReference(DEFAULT);
  digitalWrite(resetPin, LOW);
  digitalWrite(strobePin, HIGH);
}
 
void loop() {
//read pots for led color and brightness
    colorbright();
//read the msgeq7
    readMSGEQ7();
//put the eq values into array
//fillLights();
 
    for(int band=0; band<7; band++) {
      for (int led=0; led<ledsInBand; led++) {
        lightState[band][led] = (led<=bandMap[band])?colorVal:0;
      }
    }
   
    for(int band=0; band<7; band++) {
      for (int led=0; led<ledsInBand; led++) {
        strip.setPixelColor(band*7+led, lightState[band][led]);
      }
    }
   
    for (int i=0;i<7;i++)
      {
      Serial.print(bandMap[i]);
      Serial.print(" ");
      }
    Serial.println();
   
    strip.setBrightness(brightVal);
    strip.show();
}
 
 
/*
Function to set strip color and brightness     
*/
 
void colorbright() {
    bright = analogRead(brightPin);                             //read pot to get brightness for strip
    brightVal = map(bright, 0, 1023, 0, 255);   //map led brightness value for strip
 
    color = analogRead(colorPin);                               //read pin to find color value from pot
    colorMap = map(color, 0, 1023, 0, 7);               //map pin value to # of available colors set in adjColor
    colorVal = adjColor[colorMap];                              //set color to list of colors above
}
 
 
/*
Function to read the msgeq7
*/
void readMSGEQ7() {
    digitalWrite(resetPin, HIGH);
    digitalWrite(resetPin, LOW);
    for(int i=0; i<7; i++)
      {
      digitalWrite(strobePin,LOW); // strobe pin on the shield - kicks the IC up to the next band
      delayMicroseconds(30); //
      bandValue[i] = analogRead(analogPin); // store left band reading
      bandMap[i] = map(bandValue[i], 0, 900, 0, 6);  //map the band values to light positions
      //right[band] = analogRead(1); // implement later
      digitalWrite(strobePin,HIGH);
      }
}
 

Some pics of the setup until I can do something prettier

2014-12-02 18.51.39

2014-12-02 18.51.16

2014-12-02 18.51.22

11/28/14

Convert arcs to line segments with Solidworks

Ok so I figured I would add this on here so I never forget. If you need to create a .dxf that’s all line segments from a model that was made with arcs, export the models as an .stl then reimport into Solidworks. From there you can save the file and create a drawing from it and it should be all broken up into .stl lines. I was trying to create a custom board outline for eagle from a dxf using the pcg-gcode.ulp. For some reason it would not read the arcs that came from the .dxf I used for the file.

11/17/14

ESP8266 Part 2

Alright in this post I’ll go over how I set up a tcp server on the ESP to listen for commands from an android app or web app. At this point you’ll need an ESP connected to a network, a computer set up with a LAMP stack or something comparable. I’m only going to cover how to do this with linux as the php socket server. Explaining setting up a web server is beyond the scope of this and I’m not an expert on it anyways.
Disclaimer: I don’t claim any of this is secure, only do this on a network you have permission to use. I know just enough to get this working and that’s all I’ll ever claim to know.

Ok now that the disclaimer is out there proceed at your own risk.

So the easy part is setting up the TCP on the ESP

/* Simple sketch to parse out commands from TCP socket 
    and send to serial
    new and improved parsing all thanks to James Armstrong
*/

const int LED_PIN = 13;  //Set up pin for LED

void setup() {
  pinMode(LED_PIN, OUTPUT);
  Serial1.begin(115200); 
  Serial.begin(115200);
  Serial1.println("AT+RST");  //Reset the ESP8266
  delay(1000);                //Delay to let reset run
  Serial1.println("AT+CIPMODE=0");  //set cipmode to control rcv string
  delay(1000);
  Serial1.println("AT+CIPMUX=1");  //set cipmux to allow multiple connections
  delay(1000);
  Serial1.println("AT+CIPSERVER=1,8888");  //turn on tcp server
}
String command;  //String to hold commands sent to ESP

// copy from and to each port 
void loop() { 
 while(Serial.available()) 
 Serial1.write(Serial.read());  
 
 if(Serial1.available())
 {
   char c =Serial1.read();
   Serial.write(c);
   if(c == '\n')
   {
     parseCommand(command);
     command = "";
   }
   else if (c != '\r')command += c;
 }
}
 
 // Read command
void parseCommand(String com)
{
  String maincmd;
  //trying to parse out everything after the :  i.e. +IPD,0,3:off
  if (com.indexOf("+IPD")!=-1) {
    maincmd = com.substring(com.indexOf(":")+1); 
 if(maincmd.equalsIgnoreCase("off"))
 {
   digitalWrite(LED_PIN, LOW);
 } 
 else if (maincmd.equalsIgnoreCase("on")) 
 {
  digitalWrite(LED_PIN, HIGH);
 } 
 else {
       Serial.println(maincmd);
       Serial.println("\" (available commands: \"off\", \"on\")");
   } 
}
}

That is the whole program for the arduino. The commands at the top set up the TCP server on port 8888.

Serial1.println("AT+RST");  //Reset the ESP8266
  delay(1000);                //Delay to let reset run
  Serial1.println("AT+CIPMODE=0");  //set cipmode to control rcv string
  delay(1000);
  Serial1.println("AT+CIPMUX=1");  //set cipmux to allow multiple connections
  delay(1000);
  Serial1.println("AT+CIPSERVER=1,8888");  //turn on tcp server

This is the portion that will set up the server. Specifically AT+CIPSERVER=1,8888

Once you have that going it’s time to set up the php socket portion that your web or android app will talk to. I’m trying to teach myself node.js and at some point I’ll move over to that from PHP I think. Anyways, here is the code I used to set up the PHP side. I just saved this as socket.php on my server. You can name it whatever you want. I had a clean install of ubuntu 14.04 so the default apache location for the file was /var/www/html. So this file was /var/www/html/socket.php

<?php

if(!($sock = socket_create(AF_INET, SOCK_STREAM, 0)))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Couldn't create socket: [$errorcode] $errormsg \n");
}

echo "Socket created \n";
//change this line to fit your IP
if(!socket_connect($sock , 'your ESP/arduino ip' , 8888)) 
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Could not connect: [$errorcode] $errormsg \n");
}

echo "Connection established \n";

$message = $_POST['word'];

//Send the message to the server
if( ! socket_send ( $sock , $message , strlen($message) , 0))
{
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);

    die("Could not send data: [$errorcode] $errormsg \n");
}

echo "Message send successfully \n";

header('Refresh:5; url=send.html');
echo 'send another command';
?>

Make sure you change this line to hook up to your ESP

if(!socket_connect($sock , 'your ESP/arduino ip' , 8888))

AT+CIFSR=? should return the IP address for your ESP. So if your ESP IP address is 192.168.1.25 this line should look like this

if(!socket_connect($sock , '192.168.1.25' , 8888))

OK that should cover the PHP side and the arduino/ESP side. Now to slap together a quick web app to turn on that LED. Just save this file in the same directory as your socket.php file. For me it was /var/www/html. It will need to be in the root directory for your web server.

<h1>Arduino Control</h1>
<script src="http://www.google.com/jsapi"></script>
<script>google.load("jquery", "1.3")</script>
<script src="http://jquery-json.googlecode.com/files/jquery.json-2.2.min.js"></script>
<div class="input-group">
  <input type="text" class="form-control" placeholder="message" id="message">
<span id="button1" class="input-group-btn">
        <button class="btn btn-default" type="button">Go!</button>
      </span>
</div>
<span id = "status"> </span>

<script>
$('#button1').click(function(){
  $.post("socket.php",
  {
    word:$('#message').val()
  },
  function(data,status){
    alert("Data: " + data + "\nStatus: " + status);
    $('#status').text(status);
    $('#message').value = '';
  });
});


</script>

</body>
</html>

I just saved that as ledtest.html

So in your webserver root directory you should have ledtest.html and socket.php
You should be able to navigate to your ledtest page and type into the text box on or off and hit Go! and your led should turn off or on.

So if your weberver is 192.168.1.35 just go to a browser and type on 192.168.1.35/ledtest.html

In Part 3 I’ll do some more fun stuff like adding some WS2812B led’s and some “multi-threading” to the arduino program so you can exit out of the Neopixel loops I set up. I’d love to have comments on for people but I had to turn them off because of all the spammers. I’ll post some videos of this all working on youtube and people can just leave comments on there. Let google deal with the spam.

11/15/14

Got a lathe

image

image

Scored an old Atlas TH42. It’s pretty sad when an old “hobby” lathe is built better than any lathe you can buy now. Besides some minor surface rust it’s in great condition.

11/12/14

Setting up ESP8266 Part 1

This is how I set up my ESP8266 for serial communication. I’ll walk through just getting connected to a wifi network. I used a Mega2560 to do this because it has multiple hardware serial ports. If you’re going to use a USB to serial like the FT232R, this can be done with putty on windows or a terminal on linux or osx. I’ll make a walk through some other time for doing it with usb to serial, but the process is the same. I’m not doing anything new here this is all posted on other sites. Electrodragon has a great write up and a list of all the AT commands to use and their parameters and examples.

Hook the ESP8266 up according to the pinout of the module. The CH_PD pin needs to be jumpered to VCC on the ESP8266 PCB (shown in picture).

esp8266basic_bb

2014-11-12 18.59.23

Here is a very simple sketch to communicate with the wifi module. Unhook the VCC wire from the ESP8266 while you send the sketch over if you have any problems sending or receiving to the arduino. Some times I have to unhook it, then send the sketch, then plug the ESP8266 back in to get the program to take. Other times I can send programs with it connected without any problems. If in doubt unhook the ESP while transferring.


void setup() {
Serial1.begin(115200);
Serial.begin(115200);
Serial1.println("AT+RST");
}

void loop() {
while(Serial1.available())
Serial.write(Serial1.read());
while(Serial.available())
Serial1.write(Serial.read());
}

If all goes well you should see this in the serial monitor:

AT+RST

Next I set the CWMODE to 3, which is the AP+STA mode.
In the serial monitor put in AT+CWMODE=3 and you should see this.

CWMODE3

After I set the CWMODE I do an AT+RST So put AT+RST into the serial command window. I have had issues where I was unable to list available AP’s if I tried to AT+CWLAP immediately after changing CWMODE. After it resets you should be able to do an AT+CWLAP and list all available wifi networks.

AT+CWLAP

You should see a pretty list of available access points. Now it’s time to hook up to your wifi network.
AT+CWJAP=”yourSSID”,”yourpassword”
You need to put the AP SSID and password in quotes
AT+CWJAP

At this point you should be connected to your network. You can check your IP with
AT+CIFSR=?

Part 2 will be setting up a TCP server on the ESP8266 and connecting to it and turning a light off and on from a web app or android app.

11/12/14

Posting from my Nexus10

Just found out there was a wordpress android app.  Now that I know I can post from my phone or tablet I might post more.  I’ll try and post progress on the esp8266 arduino pro mini combo I’ve been working on.

image

image

I knew I’d use that tictac box one day. I plan on using this as a wifi xmas tree light controller.

09/3/13

Rsync shell script with ssh

Alright so I got my dose of hard knocks today. I was running rsync directly from crontab but I decided it was time to make a script to keep it all in one place instead of having some crazy cryptic rsync mumbo jumbo in my crontab. Anyways what I had running was working well but it didn’t exactly translate over to a script very well. This is what I tried at first……..looks good but it wasn’t.

#!/bin/sh

rsync -avz --delete -e ssh /srv/daily/test/ [email protected]:/srv/test/ > /var/log/rsync.biweekly.log 2>&1
#copy from daily bkup to remote server
/bin/echo $(/bin/date +%b_%d_%Y_%H.%M.%S) >> /var/log/rsync.biweekly.log
#put date on rsync log

This basically kept giving me a failed password. I had to check the remote server /var/log/auth.log to see what was going on. Eventually I figured out that the shell script would need to be explicitly pointed to my ssh keys. I changed the ssh to “ssh -i /dir/where/your/sshkeys/are” And that did the trick.

#!/bin/sh
rsync -avz --delete -e "ssh -i /home/test/.ssh/id_rsa" /srv/daily/test/ [email protected]:/srv/test/ > /var/log/rsync.biweekly.log 2>&1
#copy from daily bkup to remote server
/bin/echo $(/bin/date +%b_%d_%Y_%H.%M.%S) >> /var/log/rsync.biweekly.log
#put date on rsync log