пятница, 28 декабря 2012 г.

WiPrinter

Arduino + WiShield + Star TSP 600 = WiPrinter :)

Раздобыл я себе термопринтер Star TSP600 rs-232c.
И вдохновившись статьей Microprinter (и еще одной)  решил сделать себе нечто подобное но с WiFi.

Все достаточно просто. Подключать принтер к Arduino нужно через микросхему MAX233 или        
ей подобных. У меня была MAX233. Это необходимо для согласования уровней напряжений управляющих сигналов. С китайскими кабелями RS232 to USB принтер работать отказывался.

Схема подключения MAX233. Взята с сайта http://flipbit.co.uk.
Только к 20 контакту микросхемы я ничего не подключал.
Исходный код своего скетча я выложил на Github. За основу я взял пример SimpleClient  из библиотеки Wishield. Каждые 20 секунд Arduino отправляет запрос на веб-сервер и выводит на печать полученный ответ. Только для печати необходимо чтобы в начале ответа был символ '&'. А для того чтобы после печати принтер отрезал бумагу необходимо чтобы в конце сообщения был символ '&'. И естественно сообщение не должно содержать больше других символов '&'.

 

четверг, 4 февраля 2010 г.

Метод изготовления печатных плат которым пользуюсь я.

Просматривая новости с сайта instructables.com я наткнулся на статью

Custom PCB Prototyping using a Laser Cutter.

В ней описывается достаточно простой метод изготовления печатных плат.
Я как раз использую именно такой метод изготовления. И я несколько удивился наличием данной статьи. Так как этим методом могут воспользоваться далеко не все. И не в домашних условиях. Для этого метода нужен лазерный гравер, а он стоит не малых денег. У меня на работе как раз такой гравер имеется. И я в принципе сам догадался как можно его использовать в своих целях. И думаю те люди у которых есть доступ к подобного рода устройствам сами могут додуматься до такого метода. Так шо хоть это статья и познавательная, но для большинства народа мало полезная.

В данной статье используется в качестве покрытия на медь краска (вроде акриловая).
Я использую акриловую краску. До этого пытался делать используя лак для ногтей.
С лаком получилось только один раз (в самый первый). Тогда нашёлся только старый с советских времен. Потом купил черный лак для ногтей, но с ним ничего не вышло.
На первый взгляд лазер удаляет весь лак. Во всяком случае так кажется. Но если поскрести пинцетом, то видно что на меди все равно какой-то налет остается.
Который лазером никак не удаляется. Сколько бы заходов не делать и какую бы мощность не использовать. Остается налет и плата не травиться. Потом попробовал белую замазку
которой в документах ошибки исправляют. Тож не то. Отваливается во время травления.
В итоге пришел к акриловой краске которая продается в баллончиках. С ней пока проблем никаких нет.

Вообщем данная технология изготовления печатных плат весьма удобная и простая.
С помощью нее получаются качественные дорожки. У моего гравера разрешение 600dpi. Так шо в принципе можно рисовать дорожки любой толщины и изготавливать весьма компактные печатные платы.

суббота, 26 сентября 2009 г.

Freeduino Motor Shield



Наконец дошли руки до Motor Shield.
Решил осуществить управление машинкой игровым геймпадом через компьютер.
Реализовал в двух вариантах: через COM порт и через сеть Ethernet.

Вот скетч управления моторчиками машинки через COM порт:



#include
int incomingByte = 0;
int dirbpinB = 7; // up&down Direction pin for motor B is Digital 12
int speedbpinB = 6; // up&down Speed pin for motor B is Digital 9 (PWM)
int dirbpinA =4; //left&right Direction pin for motor A is Digital 13
int speedbpinA = 5; //left&right Speed pin for motor A is Digital 10 (PWM)
int speedB = 255; //Speed up&down
int speedA = 255; //Speed left&right
int up = 0; //up
int dw = 1; //dw
int lf = 0; //left
int rg = 1; //right

void setup()
{
pinMode(dirbpinA, OUTPUT);
pinMode(dirbpinB, OUTPUT);
Serial.begin(9600);
}

void loop()
{
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();

switch (incomingByte) {
case '1': // up
digitalWrite(dirbpinB, up);
analogWrite(speedbpinB, speedB);
delay(100);
break;
case '2': //down
digitalWrite(dirbpinB, dw);
analogWrite(speedbpinB, speedB);
delay(100);
break;
case '3': //left
digitalWrite(dirbpinA, lf);
analogWrite(speedbpinA, speedA);
delay(100);
break;
case '4': //right
digitalWrite(dirbpinA, rg);
analogWrite(speedbpinA, speedA);
delay(100);
break;

}

}
else{
analogWrite(speedbpinA, 0);
analogWrite(speedbpinB, 0);
}

}



Поясню. Ввиду того что я собирался подключать к Arduino еще и NKC Ethernet Shield for Arduino.
Я отвел для мотор шилда 4, 5, 6 и 7 цифровые контакты. Хотя следовал конечно использовать 13, 12 , 10 и 9. Но Ethernet Shield тоже использует 13 и 10 контакты.
Т.е. 4, 5, 6, 7 и контакты Arduino я подсоединил к 13, 10, 9, 12 контактам мотор шилда соответственно.

Для того что бы задействовать, для управления машинкой, геймпад я написал программу на C#. Т.е. нашел хороший пример на codeproject и чуть его переделал.
По сути я там исправил всего один файл frmMain.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace JoystickSample
{
public partial class frmMain : Form
{
private JoystickInterface.Joystick jst;
private SerialPort sp = new SerialPort();

public frmMain()
{
InitializeComponent();
}

private void frmMain_Load(object sender, EventArgs e)
{
// grab the joystick
jst = new JoystickInterface.Joystick(this.Handle);
string[] sticks = jst.FindJoysticks();
jst.AcquireJoystick(sticks[0]);

// add the axis controls to the axis container
for (int i = 0; i < jst.AxisCount; i++)
{
Axis ax = new Axis();
ax.AxisId = i + 1;
flpAxes.Controls.Add(ax);
}

// add the button controls to the button container
for (int i = 0; i < jst.Buttons.Length; i++)
{
JoystickSample.Button btn = new Button();
btn.ButtonId = i + 1;
btn.ButtonStatus = jst.Buttons[i];
flpButtons.Controls.Add(btn);
}

// start updating positions
tmrUpdateStick.Enabled = true;

if (!sp.IsOpen)
{
sp.PortName = "COM12";
sp.BaudRate = 9600;

try
{
sp.Open();
}
catch
{

}

}
}

private void tmrUpdateStick_Tick(object sender, EventArgs e)
{
// get status
jst.UpdateStatus();

// update the axes positions
foreach (Control ax in flpAxes.Controls)
{
if (ax is Axis)
{
switch (((Axis)ax).AxisId)
{
case 1:
((Axis)ax).AxisPos = jst.AxisA;
break;
case 2:
((Axis)ax).AxisPos = jst.AxisB;
break;
case 3:
((Axis)ax).AxisPos = jst.AxisC;
if (jst.AxisC == 65535)
{ sp.Write("4"); }
if (jst.AxisC == 0)
{ sp.Write("3"); }
break;
case 4:
((Axis)ax).AxisPos = jst.AxisD;
if (jst.AxisD == 65535)
{ sp.Write("1"); }
if (jst.AxisD == 0)
{ sp.Write("2"); }
break;
case 5:
((Axis)ax).AxisPos = jst.AxisE;
break;
case 6:
((Axis)ax).AxisPos = jst.AxisF;
break;
}
}
}

// update each button status
foreach (Control btn in flpButtons.Controls)
{
if (btn is JoystickSample.Button)
{
((JoystickSample.Button)btn).ButtonStatus =
jst.Buttons[((JoystickSample.Button)btn).ButtonId - 1];
}
}
}
}
}


С управленим через COM все.
Тепер осуществление управления через Ethernet.
Для этого подключим к Arduino помимо мотор шилда еще и Ethernet Shield.
Скетч:



#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 0, 7 };
byte gateway[] = { 192, 168, 0, 1 };
byte subnet[] = { 255, 255, 255, 0 };
Server server(23);
int incomingByte = 0;
int dirbpinB = 7; // up&down Direction pin for motor B is Digital 12
int speedbpinB = 6; // up&down Speed pin for motor B is Digital 9 (PWM)
int dirbpinA = 4; //left&right Direction pin for motor A is Digital 13
int speedbpinA = 5; //left&right Speed pin for motor A is Digital 10 (PWM)
int speedB = 255; //Speed up&down
int speedA = 255; //Speed left&right
int up = 0; //up
int dw = 1; //dw
int lf = 0; //left
int rg = 1; //right

void setup()
{
pinMode(dirbpinA, OUTPUT);
pinMode(dirbpinB, OUTPUT);
Ethernet.begin(mac, ip, gateway, subnet);
server.begin();
}

void loop()
{
Client client = server.available();
if (client) {
// read the incoming byte:
incomingByte = client.read();

switch (incomingByte) {
case '1': //up
digitalWrite(dirbpinB, up);
analogWrite(speedbpinB, speedB);
delay(200);
break;
case '2': //dw
digitalWrite(dirbpinB, dw);
analogWrite(speedbpinB, speedB);
delay(200);
break;
case '3': //left
digitalWrite(dirbpinA, lf);
analogWrite(speedbpinA, speedA);
delay(200);
break;
case '4': //right
digitalWrite(dirbpinA, rg);
analogWrite(speedbpinA, speedA);
delay(200);
break;


}
else{
analogWrite(speedbpinA, 0);
analogWrite(speedbpinB, 0);
}

}



И подправленный файл frmMain.cs из проекта:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Net.Sockets;
using System.Net;

namespace JoystickSample
{
public partial class frmMain : Form
{
private JoystickInterface.Joystick jst;
static string hostName;
static int port;
Socket socket;
public frmMain()
{
InitializeComponent();
}

private void frmMain_Load(object sender, EventArgs e)
{
// grab the joystick
jst = new JoystickInterface.Joystick(this.Handle);
string[] sticks = jst.FindJoysticks();
jst.AcquireJoystick(sticks[0]);

// add the axis controls to the axis container
for (int i = 0; i < jst.AxisCount; i++)
{
Axis ax = new Axis();
ax.AxisId = i + 1;
flpAxes.Controls.Add(ax);
}

// add the button controls to the button container
for (int i = 0; i < jst.Buttons.Length; i++)
{
JoystickSample.Button btn = new Button();
btn.ButtonId = i + 1;
btn.ButtonStatus = jst.Buttons[i];
flpButtons.Controls.Add(btn);
}

// start updating positions
tmrUpdateStick.Enabled = true;

port = 23;
hostName = Dns.GetHostName();

try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string IPserv = "192.168.0.7";
IPHostEntry host = Dns.GetHostEntry(hostName);
IPEndPoint point = new IPEndPoint(IPAddress.Parse(IPserv), port);// Задайте 2 параметра (IPAdress и порт)
socket.Connect(point); // Подключите разъем к точке point

// Console.WriteLine("Connected to {0}\n", socket.RemoteEndPoint.ToString());


}
catch //(Exception ex)
{
//Console.WriteLine(ex.Message);
}
//Console.ReadKey(true);

}

private void tmrUpdateStick_Tick(object sender, EventArgs e)
{
// get status
jst.UpdateStatus();

// update the axes positions
foreach (Control ax in flpAxes.Controls)
{
if (ax is Axis && socket.Connected)
{
switch (((Axis)ax).AxisId)
{
case 1:
((Axis)ax).AxisPos = jst.AxisA;
break;
case 2:
((Axis)ax).AxisPos = jst.AxisB;
break;
case 3:
((Axis)ax).AxisPos = jst.AxisC;
if (jst.AxisC == 65535)
{
byte[] msg = Encoding.ASCII.GetBytes("4");
socket.Send(msg);
}

if (jst.AxisC == 0)
{
byte[] msg = Encoding.ASCII.GetBytes("3");
socket.Send(msg);
}
break;
case 4:
((Axis)ax).AxisPos = jst.AxisD;
if (jst.AxisD == 65535)
{
byte[] msg = Encoding.ASCII.GetBytes("1");
socket.Send(msg);
}
if (jst.AxisD == 0)
{
byte[] msg = Encoding.ASCII.GetBytes("2");
socket.Send(msg);
}
break;
case 5:
((Axis)ax).AxisPos = jst.AxisE;
break;
case 6:
((Axis)ax).AxisPos = jst.AxisF;
break;
}
}
}

// update each button status
foreach (Control btn in flpButtons.Controls)
{
if (btn is JoystickSample.Button)
{
((JoystickSample.Button)btn).ButtonStatus =
jst.Buttons[((JoystickSample.Button)btn).ButtonId - 1];
}
}
}
}
}

В таком виде все прекрасно работет.
Хотя в данном случае стоит релиазовать подключение через Ethernet не по TCP, а по UDP

четверг, 30 июля 2009 г.

Пока только вольтметр

Задумал тут разработать проектик полезный для работы.
Пока только сварганил из Arduino вольтметр.
В перспективе хочу добавить еще датчик температуры и как-то осуществить возможность отправки SMS. Будет своего рода контроллер температуры и напряжения с возможностью SMS оповещения о сбоях.

Измеряемое напряжение находится в пределах от 0 до 60В.
60В прямо так Arduino не измерить. В таких случаях обычно с вольтметром используют шунт http://physics.5ballov.ru/Konspekt/t11.htm
Я хз как надо поступать в случае с ардуино. В интернете не нашел. Пока воспользовался двумя последовательно соединенными, между плюсом и минусом, резисторами на 1,5МОм и 82КОм. Такие большие чтоб жрали меньше тока. Резисторы рассчитаны на 1W каждый.
Arduino измеряет падение напряжения на резисторе в 82КОм. Потом это напряжение умножается на постоянный коэффициент пропорциональности и получается реальное напряжение. Для индикации измерений я подключил к Arduino также ЖК дисплей.

Вот скетч:

 
#include <LiquidCrystal.h>
// LiquidCrystal display with:
// rs on pin 12
// rw on pin 11
// enable on pin 10
// d4, d5, d6, d7 on pins 5, 4, 3, 2
LiquidCrystal lcdup(12, 11, 10, 5, 4, 3, 2),
lcddw(12, 11, 13, 5, 4, 3, 2);
void setup() {
lcdup.clear();
lcddw.clear();

}

void loop() {
float voltage = 5.0 / 1024.0 * analogRead(0);

lcdup.clear();
lcdup.print("Voltage on resistor: ");
lcdup.print(voltage);
lcdup.print(" B");
float realv = voltage * 19.3;
lcddw.clear();
lcddw.print("Real voltage: ");
lcddw.print(realv);
lcddw.print(" B");
delay(1000);


}



А вот фото:



Тут я измерял напряжение на 9В батарейке, питающей Arduino.
Измерения конечно не совсем точные. Но это все еще нужно доработать...

вторник, 9 июня 2009 г.

MailClient

На основе примера веб клиента сделал майл клиент.
 
#include "Ethernet.h"

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 0, 7 };
byte server[] = { 94, 100, 177, 6}; // pop.mail.ru
byte gw[] = { 192, 168, 0, 1 };
byte subnet[] = { 255, 255, 255, 0 };

Client client(server, 110);

void setup()
{
Ethernet.begin(mac, ip);
Serial.begin(9600);

delay(1000);

Serial.println("connecting...");

if (client.connect()) {
Serial.println("connected");
client.println("USER @mail.ru");
client.println("PASS ****");
client.println("STAT");
client.println("Quit");
} else {
Serial.println("connection failed");
}
}

void loop()
{
if (client.available()) {
char c = client.read();
Serial.print(c);
}

if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
for(;;)
;
}
}

суббота, 6 июня 2009 г.

www.nkcelectronics.com

Пришла посылка из США.
На www.nkcelectronics.com приобрел себе Ethernet Shield, Motor control shield KIT, парочку atmega328 и еще по мелочи.

Пока успел собрать тока Ethernet Shield.
Протестил скетчем web-клиент из примеров библиотеки Ethernet.
Все прекрасно сработало. Покупкой доволен :)

суббота, 10 января 2009 г.

Arduino для отладки программ.

Пишу программу на С# которая снимает показания с терморегуляторов "Поликон", рисует график зависимости температуры от времени и записывает данные в файл.
Терморегуляторы по rs-485 объединены в сеть и через интерфейсный преобразователь usb t--> rs-485 подкльченый к компютеру.
Компьютер видит все это дело как обычный Com порт, правда в данном случае он виртуальный. Что бы получить данные с прибора нужно просто послать на com порт сообщение определенного вида и затем считать с com порта поступившее сообщение.прибора
И ввиду того что у меня дома нет ни сети из терморегуляторов , ни даже хотя бы одного терморегулятора. А необходимость в отладки программы при ее написании имеется. Я запрограммировал arduino как эмулятор работы всех терморегуляторов объединненых в сеть. С Arduino тоже можно общаться просто посылая сообщения на сom порт и поэтому в программе ни чего менять ненадо.

Вот код программы Arduino:

#include stdio.h
int incomingByte = 0,
incomingByte1= 0,
newrandom = 0;
char ascii[9];

void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps

}

void loop() {

// send data only when you receive data:

if (Serial.available() == 5) {
// read the incoming byte:
incomingByte = Serial.read();

if (incomingByte == '&'){
incomingByte = Serial.read();
incomingByte1 = Serial.read();
newrandom = random(100,999);
sprintf(ascii,">%c%c+%i\n", incomingByte, incomingByte1, newrandom) ;
Serial.print(ascii);
}
}
}


Ничего тут сложного нет. Arduino просто читает данные с com порта обрабатывет и посылает на com порт ответ необходимого вида.

И в результате что получается. С компьютера мы посылаем сообщение вида:

&051\n

где & - код начала сообщения
05 - это адрес терморегулятора,
1 - код комманды
\n - код конца сообщения, возврат каретки.

А в ответ компьютер ждет сообщение вида:

>05+-36,2\n

где > - код начала сообщения
05 - адрес терморегулятора
+ - код начала строки с данными,
-36,2 - данны по температуре.
\n - код окончания, возврат каретки.

Че делает arduino. Проверяет первый символ в сообщении, если все ОК читает два следуущих символа адреса и посылает ответ нужного вида. Содержащем в себе адрес, который был в полученном сообщении, и произвольное значение температуры в диапозоне от 100 до 999 градусов. Сразу скажу что получить большое разнообразие чисел с помощью функции random(100,999) мне неудалось, но для отладки программы её было достаточно.

Вот пример посылки команды через консоль.


Вот график из моей программы, как пример ее работы с ардуино :
Тут так сказать эмулируется опрос программой двух терморегуляторов.