tag:blogger.com,1999:blog-43067040578464280122024-02-08T04:52:03.249+03:00Software RnDSoftware research and development blogXantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.comBlogger134125tag:blogger.com,1999:blog-4306704057846428012.post-32021986255282835322019-02-10T14:59:00.001+03:002019-03-27T22:36:08.504+03:00Angle meterJust released one more just-for-fun project.
<br/>
<a href="https://angle-meter.github.io/">Angle meter online</a>
<br/>
<div class="separator" style="clear: both; text-align: center;"><a href="https://angle-meter.github.io/img/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://angle-meter.github.io/img/screenshot.png" width="400" height="640" data-original-width="500" data-original-height="800" /></a></div>
Measure angles on the web.Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-48323526674160521602017-09-09T19:08:00.001+03:002017-09-09T19:08:27.236+03:00Matrix animationThis weekend's I had a bit of time and I've added ability to animate matrices in <a href="http://xantorohara.github.io/led-matrix-editor/">
LED Matrix Editor</a>.
<br/>
Also I've added color selector and refined design:
<br/>
<br/>
<a href="http://xantorohara.github.io/led-matrix-editor/">
<img src="https://github.com/xantorohara/led-matrix-editor/raw/master/resources/led-matrix-2.png"/>
</a>
<br/>
<br/>
<a href="https://xantorohara.github.io/led-matrix-editor/v1/">Previous version is available as well</a>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-2839321242520929882017-08-31T23:11:00.001+03:002018-05-09T12:57:52.714+03:00Create, get, remove datatable relations in Spotfire using Python <div class="docbook">
<h2>Create, get, remove datatable relations in Spotfire using Python</h2>
<p>Imagine you have a data table with countries:</p>
<table>
<thead>
<tr>
<th>Country code</th>
<th>Country name</th>
</tr>
</thead>
<tbody>
<tr>
<td>HKG</td>
<td>Hong Kong</td>
</tr>
<tr>
<td>ISR</td>
<td>Israel</td>
</tr>
<tr>
<td>MYS</td>
<td>Malaysia</td>
</tr>
</tbody>
</table>
<p>And data table with languages related to these countries:</p>
<table>
<thead>
<tr>
<th>Country code</th>
<th>Language</th>
<th>Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<td>HKG</td>
<td>Canton Chinese</td>
<td>88.7</td>
</tr>
<tr>
<td>HKG</td>
<td>Chiu chau</td>
<td>1.4</td>
</tr>
<tr>
<td>HKG</td>
<td>English</td>
<td>2.2</td>
</tr>
<tr>
<td>HKG</td>
<td>Fukien</td>
<td>1.9</td>
</tr>
<tr>
<td>HKG</td>
<td>Hakka</td>
<td>1.6</td>
</tr>
<tr>
<td>ISR</td>
<td>Arabic</td>
<td>18.0</td>
</tr>
<tr>
<td>ISR</td>
<td>Hebrew</td>
<td>63.1</td>
</tr>
<tr>
<td>ISR</td>
<td>Russian</td>
<td>8.9</td>
</tr>
<tr>
<td>MYS</td>
<td>Chinese</td>
<td>9.0</td>
</tr>
<tr>
<td>MYS</td>
<td>Dusun</td>
<td>1.1</td>
</tr>
<tr>
<td>MYS</td>
<td>English</td>
<td>1.6</td>
</tr>
<tr>
<td>MYS</td>
<td>Iban</td>
<td>2.8</td>
</tr>
<tr>
<td>MYS</td>
<td>Malay</td>
<td>58.4</td>
</tr>
<tr>
<td>MYS</td>
<td>Tamil</td>
<td>3.9</td>
</tr>
</tbody>
</table>
<p>Where "Country code" is the common field.</p>
<p>You would like to create link between these tables.
It is possible to create relation manually in Spotfire,
but for some reason you need to create it automatically via Python script. </p>
<h3>Create relation between tables</h3>
<pre><code class="py">def add_relation(table1, table2, link_expression):
Document.Data.Relations.Add(
Document.Data.Tables[table1],
Document.Data.Tables[table2],
link_expression)
</code></pre>
<p>Usage:</p>
<pre><code class="py">add_relation("country", "lang", "[lang].[Country code]=[country].[Country code]")
</code></pre>
<p>Now you are able to select country in the "country" table
and all related languages from the "lang" table will also be selected. </p>
<p>Like here:</p>
<p><img alt="Spotfire linked tables" src="https://xantorohara.github.io/howto-spotfire/spotfire-py-create-get-remove-relation/screen.png" /></p>
<h3>Get relation expression</h3>
<pre><code class="py">def get_relation(table1, table2):
return Document.Data.Relations.FindRelation(
Document.Data.Tables[table1],
Document.Data.Tables[table2])
</code></pre>
<p>Usage:</p>
<pre><code class="py">print(get_relation("country", "lang").Expression)
# [lang].[Country code]=[country].[Country code]
</code></pre>
<h3>Delete relation</h3>
<pre><code class="py">def del_relation(table1, table2):
relation = Document.Data.Relations.FindRelation(
Document.Data.Tables[table1],
Document.Data.Tables[table2])
if relation:
Document.Data.Relations.Remove(relation)
</code></pre>
<p>Usage:</p>
<pre><code class="py">del_relation("country", "lang")
</code></pre>
<p> See more about Spotfire on <a href="https://xantorohara.github.io/howto-spotfire/">GitHub</a>
</p>
<p>
<small>
<i>Xantorohara, </i><i title="YYYY-MM-DD">2017-08-31,</i> <i>Spotfire 7.8.0 </i>
</small>
</p>
</div>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-12761149711476347672017-08-30T01:23:00.001+03:002018-05-09T12:58:24.242+03:00Check that Spotfire document has a Visualization on a Page using Python<div class="docbook">
<h2>Check that Spotfire document has a Visualization on a Page using Python</h2>
<p>Just use this simple Python function:</p>
<pre><code class="py">def has_visualization(page_name, vis_name):
for page in Document.Pages:
if page.Title == page_name:
for vis in page.Visuals:
if vis.Title == vis_name:
return True
</code></pre>
<p>Try it:</p>
<pre><code class="py">print(has_visualization("SomePage", "SomeChart")) # True
print(has_visualization("SomePage", "ChartNotExists")) # None
</code></pre>
<p><img alt="Spotfire Visualization" src="https://xantorohara.github.io/howto-spotfire/spotfire-py-detect-visualization-exists/screen.png" /></p>
<p> See more about Spotfire on <a href="https://xantorohara.github.io/howto-spotfire/">GitHub</a>
</p>
<p>
<small>
<i>Xantorohara, </i><i title="YYYY-MM-DD">2017-08-30,</i> <i>Spotfire 7.8.0 </i>
</small>
</p>
</div>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com1tag:blogger.com,1999:blog-4306704057846428012.post-84540627463626392302017-08-30T01:05:00.000+03:002018-05-09T12:58:52.332+03:00Check that Spotfire document has a Page using Python<div class="docbook">
<h2>Check that Spotfire document has a Page using Python</h2>
<p>Just use this simple Python function:</p>
<pre><code class="py">def has_page(page_name):
for page in Document.Pages:
if page.Title == page_name:
return True
</code></pre>
<p>Try it:</p>
<pre><code class="py">print(has_page("Page")) # True
print(has_page("Page (2)")) # True
print(has_page("SomePage")) # True
print(has_page("PageNotExists")) # None
</code></pre>
<p><img alt="Spotfire Pages" src="https://xantorohara.github.io/howto-spotfire/spotfire-py-detect-page-exists/screen.png" /></p>
<p> See more about Spotfire on <a href="https://xantorohara.github.io/howto-spotfire/">GitHub</a>
</p>
<p>
<small>
<i>Xantorohara, </i><i title="YYYY-MM-DD">2017-08-30,</i> <i>Spotfire 7.8.0 </i>
</small>
</p>
</div>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-54201347822443191682017-08-30T00:41:00.000+03:002018-05-09T12:57:13.709+03:00Show URLs in Spotfire Table<div class="docbook">
<h2>Show URLs in Spotfire Table</h2>
<p>Spotfire uses auto-detection to set URL renderer for a table column.
So, if all values in a column start with "http://" or "https://" it sets URL renderer.</p>
<p>Like here:</p>
<p><img alt="Spotfire table with URLs" src="https://xantorohara.github.io/howto-spotfire/spotfire-table-url-column/screen-1.png" /></p>
<p>Moreover, it is possible to set URL renderer for columns in which the values do not look like URLs.
But these values can be used as parameters for URLs.</p>
<p>Like here in the "Param Links" column:</p>
<p><img alt="Spotfire table parameterized URLs" src="https://xantorohara.github.io/howto-spotfire/spotfire-table-url-column/screen-2.png" /></p>
<p>The only step you need is to specify URL with a placeholder:</p>
<p><img alt="Spotfire URL renderer settings" src="https://xantorohara.github.io/howto-spotfire/spotfire-table-url-column/screen-4.png" /></p>
<p>via "Table Properties->Columns"</p>
<p><img alt="Spotfire column properties" src="https://xantorohara.github.io/howto-spotfire/spotfire-table-url-column/screen-3.png" /></p>
<p>Don't forget to choose "Link" as a "Renderer".</p>
<p> See more about Spotfire on <a href="https://xantorohara.github.io/howto-spotfire/">GitHub</a>
</p>
<p>
<small>
<i>Xantorohara, </i><i title="YYYY-MM-DD">2017-08-30,</i> <i>Spotfire 7.8.0 </i>
</small>
</p>
</div>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-87596124734039109242017-08-29T11:02:00.000+03:002017-08-29T11:09:45.914+03:00Show images in Spotfire Table<div class="docbook">
<h2>Show images in Spotfire Table</h2>
<p>Imagine that you have a table like this:</p>
<table>
<thead>
<tr>
<th>Service Name</th>
<th>Service Id</th>
</tr>
</thead>
<tbody>
<tr>
<td>Slack</td>
<td>slackhq</td>
</tr>
<tr>
<td>Travis CI</td>
<td>travis-ci</td>
</tr>
<tr>
<td>Zenhubio</td>
<td>zenhubio</td>
</tr>
<tr>
<td>Atom</td>
<td>atom</td>
</tr>
</tbody>
</table>
<p>And you would like to see icon images in the "Service Id" column.</p>
<p>You know there is a storage with images, with URLs like this:</p>
<pre><code class="text">https://assets-cdn.github.com/images/modules/site/integrators/${Service Id}.png
</code></pre>
<p>So, actually these images should be used instead of appropriate "Service Ids": </p>
<pre><code class="text">https://assets-cdn.github.com/images/modules/site/integrators/slackhq.png
https://assets-cdn.github.com/images/modules/site/integrators/travis-ci.png
https://assets-cdn.github.com/images/modules/site/integrators/zenhubio.png
https://assets-cdn.github.com/images/modules/site/integrators/atom.png
</code></pre>
<p>It is easy to achieve it in the Spotfire:</p>
<ul>
<li>Open "Table Properties" -> "Columns" </li>
<li>Select column</li>
<li>Set "Renderer" type as "Image from URL"</li>
<li>Click "Settings..." and put your URL with {$} as a placeholder</li>
</ul>
<p><img alt="Spotfire screenshot" src="https://xantorohara.github.io/spotfire-internals/spotfire-table-image-column/screenshot.png" /></p>
<p>Now you have pretty images in Spotfire Table</p>
<p> See more on <a href="https://xantorohara.github.io/spotfire-internals/">GitHub</a>
</p>
<p>
<small>
<i>Xantorohara, </i><i title="YYYY-MM-DD">2017-08-29,</i> <i>Spotfire 7.8.0 </i>
</small>
</p>
</div>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-37575328367384574702017-06-17T18:08:00.000+03:002017-06-17T18:08:13.650+03:00SBDF and STDF table viewerAs I mentioned in previous post - <a href="https://xantorohara.github.io/rocket-table/">Rocket table</a> supports not only SAS (.sas7bdat) files.
It also supports SBDF (Spotfire Binary Data File) and STDF (Spotfire Text Data File) file formats.
Now you do not have to have expensive Spotfire installed in your system. Just use Rocket table it is pretty fast and compact.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://xantorohara.github.io/rocket-table/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="474" data-original-width="800" height="379" src="https://xantorohara.github.io/rocket-table/screenshot.png" width="640" /></a></div>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-49347629572929910522017-06-17T17:57:00.000+03:002017-06-17T17:57:17.759+03:00SAS table viewerCouple of years ago I implemented viewer for SAS (.sas7bdat) files.
It was <a href="http://xantorohara.github.io/sas-table-explorer/">SAS Table Explorer</a>.
Actually now it is not only viewer for SAS files, but it also supports other table formats.
I decided to rename that application to <a href="https://xantorohara.github.io/rocket-table/">
Rocket Table</a> and continue development under this new project.Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-11739053305285699492017-02-06T22:03:00.003+03:002017-02-06T22:03:35.137+03:00Spring Boot plugin duplicates dependencies<div class="markdown-body">
<p>Recently I found that Spring Boot Maven plugin duplicates some dependencies in the output war file.
The problem with time-stamped snapshot dependencies (they have versions like "1.1-20170206.160055-1").
In this case Spring Boot plugin puts both "1.1-SNAPSHOT" and "1.1-20170206.160055-1" versions of jars.
Like here:</p>
<pre><code class="text">demo-webapp-1.1-20170206.160055-1.war:\WEB-INF\lib\
demo-core-1.1-SNAPSHOT.jar
demo-core-1.1-20170206.160055-1.jar
</code></pre>
<p>This is not critical (application will work), but unpleasant.</p>
<p>The problem occurs with a Spring Boot Maven plugin version before 1.4.4.
With 1.4.4 it works fine. So just switch plugin to the 1.4.4, even if you use are using an earlier version of Spring Boot.</p>
<pre><code class="xml"><plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.4.4.RELEASE</version>
</plugin>
...
</code></pre>
<p>After that it will keep only one file per dependency:</p>
<pre><code class="txt">demo-webapp-1.1-20170206.160055-1.war:\WEB-INF\lib\
demo-core-1.1-SNAPSHOT.jar
</code></pre>
</div>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-3628177848241762952017-02-04T22:07:00.001+03:002017-02-04T22:07:46.214+03:00Install Arch linux in the VirtualBox<div class="markdown-body">
<h2>Precondition</h2>
<ul>
<li>you have boot into the newly created virtual machine from the Arch live iso</li>
</ul>
<h2>Make new single partition using whole disk space</h2>
<pre><code class="sh">parted --script /dev/sda mklabel msdos mkpart primary 0% 100% set 1 boot on print
mkfs.ext4 /dev/sda1
</code></pre>
<h2>Choose a fast mirror</h2>
<p>Edit <code>/etc/pacman.d/mirrorlist</code> file, move your preferred server to the top of the file</p>
<h2>Install base system</h2>
<pre><code class="bash">mount /dev/sda1 /mnt
pacstrap /mnt base
genfstab -p /mnt > /mnt/etc/fstab
</code></pre>
<h2>Configure base system</h2>
<pre><code class="bash">arch-chroot /mnt
echo en_US.UTF-8 UTF-8 >/etc/locale.gen
localegen
echo LANG=en_US.UTF-8 >/etc/locale.conf
echo a1 >/etc/hostname
ln -s /usr/share/zoneinfo/UTC /etc/localtime
mkinitcpio -p linux
packman -S grub sudo mc bash-completion openssh
</code></pre>
<h2>Configure network</h2>
<pre><code class="bash">ip link
systemctl enable dhcpcd@enp0s3.service
systemctl enable sshd.service
</code></pre>
<h2>Create a user</h2>
<pre><code class="bash">useradd -m -g users -G wheel -s /bin/bash username
passwd username
</code></pre>
<h2>Install boot loader</h2>
<pre><code class="bash">grub-mkconfig -o /boot/grub/grub.cfg
grub-install /dev/sda
</code></pre>
<h2>Reboot</h2>
<pre><code class="bash">exit
umount /mnt
reboot
</code></pre>
<h2>Enjoy your new Arch</h2>
</div>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-80044405598070829372017-02-04T21:57:00.001+03:002018-07-15T15:59:38.370+03:00Get Spring Boot sources<div class="docbook">
<h1>
Spring Boot sources</h1>
Very often it is helpful for me to look into the Spring sources in order to understand how some internals work.
Of course it is pretty simple to automatically download and view sources using IDE (like IntelliJ IDEA).
But sometimes I need just plain source files.<br />
I get these files using "Maven Dependency Plugin" and this pom.xml file:<br />
<pre><code><?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.xantorohara.springfield</groupId>
<artifactId>spring-boot-sources</artifactId>
<version>0.1</version>
<packaging>pom</packaging>
<name>spring-boot-sources</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- Spring Boot and Spring Framework libraries -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- My current needs -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<classifier>sources</classifier>
<outputDirectory>target</outputDirectory>
<includeGroupIds>
org.springframework,
org.springframework.boot,
org.mybatis,
org.mybatis.spring.boot
</includeGroupIds>
<useSubDirectoryPerArtifact>true</useSubDirectoryPerArtifact>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
</code></pre>
Download source code into the <em>target</em> directory using this command:<br />
<pre><code class="sh">mvn process-sources
</code></pre>
Just add another dependencies if you need.<br />
</div>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-87331849377657614672017-02-04T17:07:00.001+03:002017-02-04T17:07:24.003+03:00Oracle LOB storage in row<div class="markdown-body">
<p>Do you know how Oracle stores LOB data with "ENABLE STORAGE IN ROW" and "COMPRESS"/"NOCOMPRESS" options?</p>
<p>According to the Oracle documentation:</p>
<blockquote>
<p>The maximum amount of LOB data stored in the row is the maximum
VARCHAR2 size (4000). This includes the control information as well as
the LOB value. If you indicate that the LOB should be stored in the row,
once the LOB value and control information is larger than approximately
4000, then the LOB value is automatically moved out of the row.</p>
</blockquote>
<p>Create test tablespaces and table:</p>
<pre><code class="lang-sql">-- DROP TABLESPACE XTEST_DAT INCLUDING CONTENTS AND DATAFILES;
-- DROP TABLESPACE XTEST_LOB INCLUDING CONTENTS AND DATAFILES;
CREATE TABLESPACE XTEST_DAT DATAFILE '/oracle_tablespaces/xtest_dat.dat' SIZE 10M AUTOEXTEND ON;
CREATE TABLESPACE XTEST_LOB DATAFILE '/oracle_tablespaces/xtest_lob.dat' SIZE 10M AUTOEXTEND ON;
CREATE TABLE xtest_text
(
text CLOB
)
TABLESPACE XTEST_DAT
LOB (text) STORE AS SECUREFILE (
TABLESPACE XTEST_LOB ENABLE STORAGE IN ROW CHUNK 8192
NOCACHE LOGGING NOCOMPRESS KEEP_DUPLICATES
);
</code></pre>
<p>SQL for retrieving tablespaces size:</p>
<pre><code class="lang-sql">SELECT TABLESPACE_NAME, SUM(BYTES) BYTES
FROM USER_SEGMENTS
WHERE TABLESPACE_NAME LIKE 'XTEST_%'
GROUP BY TABLESPACE_NAME;
</code></pre>
<p>Rows generator:</p>
<pre><code class="lang-sql">-- INSERT INTO xtest_text VALUES ('1');
-- COMMIT;
DECLARE
string CLOB;
multiplier NUMBER:=1;
BEGIN
FOR i IN 1..multiplier
LOOP
string:= string || dbms_random.string('A', 1000);
END LOOP;
FOR i IN 1..1000
LOOP
INSERT INTO xtest_text VALUES (string);
END LOOP;
COMMIT;
END;
</code></pre>
<p>Follow these steps:</p>
<ul>
<li>run with multiplier = 1 to fill table with 1000 rows size of 1000 bytes</li>
<li>check tablespaces size</li>
<li>run with multiplier = 10 to fill table with 1000 rows size of 10000 bytes</li>
<li>check tablespaces size</li>
<li>run with multiplier = 5 to fill table with 1000 rows size of 5000 bytes</li>
<li>check tablespaces size</li>
</ul>
<p>Actual results:</p>
<p>With NOCOMPRESS option:</p>
<table>
<thead>
<tr>
<th>Tablespace name</th>
<th>Tablespace size</th>
<th>Tablespace size</th>
<th>Tablespace size</th>
<th>Tablespace size</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>Inserted 1 row sizeof 1 byte</td>
<td>+ 1000 rows size of 1K</td>
<td>+ 1000 rows size of 10K</td>
<td>+ 1000 rows size of 5K</td>
</tr>
<tr>
<td>XTEST_LOB</td>
<td>196608</td>
<td>196608</td>
<td><strong>20185088</strong></td>
<td><strong>27525120</strong></td>
</tr>
<tr>
<td>XTEST_DAT</td>
<td>65536</td>
<td><strong>2097152</strong></td>
<td>2097152</td>
<td>2097152</td>
</tr>
</tbody>
</table>
<p>All records size of 1K (with size less than 4000 bytes) are stored in the DAT tablespace.
All records size of 10K and 5K (with size more than 4000 bytes) are in the LOB tablespace.</p>
<p>With COMPRESS option:</p>
<table>
<thead>
<tr>
<th>Tablespace name</th>
<th>Tablespace size</th>
<th>Tablespace size</th>
<th>Tablespace size</th>
<th>Tablespace size</th>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td>Inserted 1 row sizeof 1 byte</td>
<td>+ 1000 rows size of 1K</td>
<td>+ 1000 rows size of 10K</td>
<td>+ 1000 rows size of 5K</td>
</tr>
<tr>
<td>XTEST_LOB</td>
<td>196608</td>
<td>196608</td>
<td><strong>10747904</strong></td>
<td>10747904</td>
</tr>
<tr>
<td>XTEST_DAT</td>
<td>65536</td>
<td><strong>1048576</strong></td>
<td>2097152</td>
<td><strong>9437184</strong></td>
</tr>
</tbody>
</table>
<p>All records size of 1K (with size less than 4000 bytes) are stored in the DAT tablespace.
All records size of 10K (with compressed size more than 4000 bytes) are in the LOB tablespace and partially in DAT.
All records size of 5K (with compressed size less than 4000 bytes) are stored in the DAT tablespace.</p>
</div>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-78704064016392123022015-09-28T02:24:00.001+03:002015-09-28T02:27:35.565+03:00Arduino: store 64-bit integers in PROGMEM<p>Nowadays developers don't think about bits, bytes or kilobytes.</p>
<p>How much memory is allocated for the object? Who the hell cares?!</p>
<p>Honestly speaking, modern software does fairly simple things, but it requires gigabytes of memory; much more than they actually needed. </p>
<p>But with Arduino each byte is under control. And I like it. Simple programs works in a simple way and requires reasonable amount of resources.</p>
<p>Modern Arduino (based on ATmega328P) has:</p>
<ul>
<li>2 KB of RAM</li>
<li>32 KB of Flash</li>
<li>1KB of EEPROM</li>
</ul>
<p>Much enough memory for good program )</p>
<p>It is possible to store the data in the Flash area via the PROGMEM modifier in the code.
If you going to use the data from the Flash (PROGMEM) then you have to read it back into RAM.</p>
<p>I found it useful to keep 8x8 animation (created using the <a href="http://xantorohara.github.io/led-matrix-editor/">LED Matrix Editor</a>) for LED dot matrix in the Flash instead of RAM. In my program each image is a 64-bit unsigned integer (uint64_t); an animation - is a series of these images.</p>
<h3>How to store an array of uint64_t in PROGMEM:</h3>
<pre><code>const uint64_t IMAGES[] PROGMEM = {
0x0000000000000000,
0x7c92aa82aa827c00,
0x7ceed6fed6fe7c00,
...
};
</code></pre>
<h3>How to read single(i) uint64_t from the array from PROGMEM:</h3>
<pre><code> uint64_t image;
memcpy_P(&image, &IMAGES[i], 8);
displayImage(image);
</code></pre>
<p>Just copy 8 (single uint64_t) bytes from the Flash to RAM.</p>
<p>Two sketches below show the small differences in the code, but big difference in memory usage.</p>
<h3>Store images in the RAM:</h3>
<pre><code class="lang-c">#include <LedControl.h>
const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;
const uint64_t IMAGES[] = {
0x0000000000000000,
0x7c92aa82aa827c00,
0x7ceed6fed6fe7c00,
0x10387cfefeee4400,
0x10387cfe7c381000,
0x381054fe54381000,
0x38107cfe7c381000,
0x00387c7c7c380000,
0xffc7838383c7ffff,
0x0038444444380000,
0xffc7bbbbbbc7ffff,
0x0c12129ca0c0f000,
0x38444438107c1000,
0x060e0c0808281800,
0x066eecc88898f000,
0x105438ee38541000,
0x061e7efe7e1e0600,
0xc0f0fcfefcf0c000,
0x1038541054381000,
0x6666006666666600,
0xa0a0a0bca6a6fc00,
0x0c324824124c3000,
0xfefefe0000000000,
0x7c38541054381000,
0x383838fe7c381000,
0x10387cfe38383800,
0x10307efe7e301000,
0x1018fcfefc181000,
0xfefe0e0e0e000000,
0x002844fe44280000,
0xfefe7c7c38381000,
0x1038387c7cfefe00,
0x0000000000000000,
0x180018183c3c1800,
0x00000000286c6c00,
0x6c6cfe6cfe6c6c00,
0x103c403804781000,
0x60660c1830660600,
0xfc66a6143c663c00,
0x0000000c18181800,
0x060c1818180c0600,
0x6030181818306000,
0x006c38fe386c0000,
0x0010107c10100000,
0x060c0c0c00000000,
0x0000003c00000000,
0x0606000000000000,
0x00060c1830600000,
0x3c66666e76663c00,
0x7e1818181c181800,
0x7e060c3060663c00,
0x3c66603860663c00,
0x30307e3234383000,
0x3c6660603e067e00,
0x3c66663e06663c00,
0x1818183030667e00,
0x3c66663c66663c00,
0x3c66607c66663c00,
0x0018180018180000,
0x0c18180018180000,
0x6030180c18306000,
0x00003c003c000000,
0x060c1830180c0600,
0x1800183860663c00,
0x003c421a3a221c00,
0x6666667e66663c00,
0x3e66663e66663e00,
0x3c66060606663c00,
0x3e66666666663e00,
0x7e06063e06067e00,
0x0606063e06067e00,
0x3c66760606663c00,
0x6666667e66666600,
0x3c18181818183c00,
0x1c36363030307800,
0x66361e0e1e366600,
0x7e06060606060600,
0xc6c6c6d6feeec600,
0xc6c6e6f6decec600,
0x3c66666666663c00,
0x06063e6666663e00,
0x603c766666663c00,
0x66361e3e66663e00,
0x3c66603c06663c00,
0x18181818185a7e00,
0x7c66666666666600,
0x183c666666666600,
0xc6eefed6c6c6c600,
0xc6c66c386cc6c600,
0x1818183c66666600,
0x7e060c1830607e00,
0x7818181818187800,
0x006030180c060000,
0x1e18181818181e00,
0x0000008244281000,
0xfe00000000000000,
0x0000000060303000,
0x7c667c603c000000,
0x3e66663e06060600,
0x3c6606663c000000,
0x7c66667c60606000,
0x3c067e663c000000,
0x0c0c3e0c0c6c3800,
0x3c607c66667c0000,
0x6666663e06060600,
0x3c18181800180000,
0x1c36363030003000,
0x66361e3666060600,
0x1818181818181800,
0xd6d6feeec6000000,
0x6666667e3e000000,
0x3c6666663c000000,
0x06063e66663e0000,
0xf0b03c36363c0000,
0x060666663e000000,
0x3e403c027c000000,
0x1818187e18180000,
0x7c66666666000000,
0x183c666600000000,
0x7cd6d6d6c6000000,
0x663c183c66000000,
0x3c607c6666000000,
0x3c0c18303c000000,
0x7018180c18187000,
0x1818180018181800,
0x0e18183018180e00,
0x000000365c000000,
0xfe8282c66c381000
};
const int IMAGES_LEN = sizeof(IMAGES)/8;
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);
void setup() {
display.clearDisplay(0);
display.shutdown(0, false);
display.setIntensity(0, 10);
}
void displayImage(uint64_t image) {
for (int i = 0; i < 8; i++) {
byte row = (image >> i * 8) & 0xFF;
for (int j = 0; j < 8; j++) {
display.setLed(0, i, j, bitRead(row, j));
}
}
}
int i = 0;
void loop() {
uint64_t image = IMAGES[i];
displayImage(image);
if (++i >= IMAGES_LEN ) {
i = 0;
}
delay(1000);
}
</code></pre>
<pre><code>Sketch uses 3,424 bytes (10%) of program storage space.
Maximum is 32,256 bytes.
Global variables use 1,123 bytes (54%) of dynamic memory,
leaving 925 bytes for local variables. Maximum is 2,048 bytes.
</code></pre>
<h3>Store images on the Flash:</h3>
<pre><code class="lang-c">#include <LedControl.h>
const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;
const uint64_t IMAGES[] PROGMEM = {
0x0000000000000000,
0x7c92aa82aa827c00,
0x7ceed6fed6fe7c00,
0x10387cfefeee4400,
0x10387cfe7c381000,
0x381054fe54381000,
0x38107cfe7c381000,
0x00387c7c7c380000,
0xffc7838383c7ffff,
0x0038444444380000,
0xffc7bbbbbbc7ffff,
0x0c12129ca0c0f000,
0x38444438107c1000,
0x060e0c0808281800,
0x066eecc88898f000,
0x105438ee38541000,
0x061e7efe7e1e0600,
0xc0f0fcfefcf0c000,
0x1038541054381000,
0x6666006666666600,
0xa0a0a0bca6a6fc00,
0x0c324824124c3000,
0xfefefe0000000000,
0x7c38541054381000,
0x383838fe7c381000,
0x10387cfe38383800,
0x10307efe7e301000,
0x1018fcfefc181000,
0xfefe0e0e0e000000,
0x002844fe44280000,
0xfefe7c7c38381000,
0x1038387c7cfefe00,
0x0000000000000000,
0x180018183c3c1800,
0x00000000286c6c00,
0x6c6cfe6cfe6c6c00,
0x103c403804781000,
0x60660c1830660600,
0xfc66a6143c663c00,
0x0000000c18181800,
0x060c1818180c0600,
0x6030181818306000,
0x006c38fe386c0000,
0x0010107c10100000,
0x060c0c0c00000000,
0x0000003c00000000,
0x0606000000000000,
0x00060c1830600000,
0x3c66666e76663c00,
0x7e1818181c181800,
0x7e060c3060663c00,
0x3c66603860663c00,
0x30307e3234383000,
0x3c6660603e067e00,
0x3c66663e06663c00,
0x1818183030667e00,
0x3c66663c66663c00,
0x3c66607c66663c00,
0x0018180018180000,
0x0c18180018180000,
0x6030180c18306000,
0x00003c003c000000,
0x060c1830180c0600,
0x1800183860663c00,
0x003c421a3a221c00,
0x6666667e66663c00,
0x3e66663e66663e00,
0x3c66060606663c00,
0x3e66666666663e00,
0x7e06063e06067e00,
0x0606063e06067e00,
0x3c66760606663c00,
0x6666667e66666600,
0x3c18181818183c00,
0x1c36363030307800,
0x66361e0e1e366600,
0x7e06060606060600,
0xc6c6c6d6feeec600,
0xc6c6e6f6decec600,
0x3c66666666663c00,
0x06063e6666663e00,
0x603c766666663c00,
0x66361e3e66663e00,
0x3c66603c06663c00,
0x18181818185a7e00,
0x7c66666666666600,
0x183c666666666600,
0xc6eefed6c6c6c600,
0xc6c66c386cc6c600,
0x1818183c66666600,
0x7e060c1830607e00,
0x7818181818187800,
0x006030180c060000,
0x1e18181818181e00,
0x0000008244281000,
0xfe00000000000000,
0x0000000060303000,
0x7c667c603c000000,
0x3e66663e06060600,
0x3c6606663c000000,
0x7c66667c60606000,
0x3c067e663c000000,
0x0c0c3e0c0c6c3800,
0x3c607c66667c0000,
0x6666663e06060600,
0x3c18181800180000,
0x1c36363030003000,
0x66361e3666060600,
0x1818181818181800,
0xd6d6feeec6000000,
0x6666667e3e000000,
0x3c6666663c000000,
0x06063e66663e0000,
0xf0b03c36363c0000,
0x060666663e000000,
0x3e403c027c000000,
0x1818187e18180000,
0x7c66666666000000,
0x183c666600000000,
0x7cd6d6d6c6000000,
0x663c183c66000000,
0x3c607c6666000000,
0x3c0c18303c000000,
0x7018180c18187000,
0x1818180018181800,
0x0e18183018180e00,
0x000000365c000000,
0xfe8282c66c381000
};
const int IMAGES_LEN = sizeof(IMAGES)/8;
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);
void setup() {
display.clearDisplay(0);
display.shutdown(0, false);
display.setIntensity(0, 10);
}
void displayImage(uint64_t image) {
for (int i = 0; i < 8; i++) {
byte row = (image >> i * 8) & 0xFF;
for (int j = 0; j < 8; j++) {
display.setLed(0, i, j, bitRead(row, j));
}
}
}
int i = 0;
void loop() {
uint64_t image;
memcpy_P(&image, &IMAGES[i], 8);
displayImage(image);
if (++i >= IMAGES_LEN ) {
i = 0;
}
delay(1000);
}
</code></pre>
<pre><code>Sketch uses 3,470 bytes (10%) of program storage space.
Maximum is 32,256 bytes.
Global variables use 99 bytes (4%) of dynamic memory,
leaving 1,949 bytes for local variables. Maximum is 2,048 bytes.
</code></pre>
<p>As you can see - the second (PROGMEM) program uses more than 10 times less RAM memory than the first.</p>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-80459715285554461002015-09-19T12:42:00.000+03:002017-05-26T01:49:41.099+03:00Arduino: LED Matrix state as array of bytes<p>Recently I released and have written about
<a href="http://xantorohara.blogspot.ru/2015/09/arduino-led-matrix-editor.html">Arduino: LED Matrix Editor</a></p>
<p>This is online editor for LED dot matrices, that helps people to make animations and save them as C-code for Arduino.
In that version was only option to save matrices as unsigned 64-bit integers (uint64_t).
I prefer this form as the most compact representation of the 8x8 matrix.</p>
<p>However some people experiencing problems with uint64_t data type (due to limitation in their software or hardware).
In order to support this case (and make them happy) I just added a new option to save images as arrays of bytes in binary form:</p>
<p><img alt="LED Matrix as byte array" class="blog-image" src="https://raw.githubusercontent.com/xantorohara/led-matrix-editor/master/resources/led-matrix-editor-bytes.png" /></p>
<p>Generated arrays take much more lines of code. But, nevertheless, they are more evident.</p>
<p>Here is a sample how to animate matrix using this code:</p>
<pre><code class="lang-c">#include <LedControl.h>
const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;
const byte IMAGES[][8] = {
{
B00010000,
B00110000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00111000
}, {
B00111000,
B01000100,
B00000100,
B00000100,
B00001000,
B00010000,
B00100000,
B01111100
}, {
B00111000,
B01000100,
B00000100,
B00011000,
B00000100,
B00000100,
B01000100,
B00111000
}, {
B00000100,
B00001100,
B00010100,
B00100100,
B01000100,
B01111100,
B00000100,
B00000100
}, {
B01111100,
B01000000,
B01000000,
B01111000,
B00000100,
B00000100,
B01000100,
B00111000
}, {
B00111000,
B01000100,
B01000000,
B01111000,
B01000100,
B01000100,
B01000100,
B00111000
}, {
B01111100,
B00000100,
B00000100,
B00001000,
B00010000,
B00100000,
B00100000,
B00100000
}, {
B00111000,
B01000100,
B01000100,
B00111000,
B01000100,
B01000100,
B01000100,
B00111000
}, {
B00111000,
B01000100,
B01000100,
B01000100,
B00111100,
B00000100,
B01000100,
B00111000
}, {
B00111000,
B01000100,
B01000100,
B01000100,
B01000100,
B01000100,
B01000100,
B00111000
}
};
const int IMAGES_LEN = sizeof(IMAGES) / 8;
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);
void setup() {
display.clearDisplay(0);
display.shutdown(0, false);
display.setIntensity(0, 5);
}
void displayImage(const byte* image) {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
display.setLed(0, i, j, bitRead(image[i], 7 - j));
}
}
}
int i = 0;
void loop() {
displayImage(IMAGES[i]);
if (++i >= IMAGES_LEN ) {
i = 0;
}
delay(333);
}
</code></pre>
<p>Animation video:</p>
<video width="640" height="360" controls preload="auto" poster="https://raw.githubusercontent.com/xantorohara/led-matrix-editor/master/resources/MAH02166_960x540.jpg"><source src="https://raw.githubusercontent.com/xantorohara/led-matrix-editor/master/resources/MAH02166_960x540.mp4" type="video/mp4"></video>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com5tag:blogger.com,1999:blog-4306704057846428012.post-17084471827783905642015-09-12T21:57:00.001+03:002017-05-26T01:44:22.625+03:00Arduino: LED Matrix Editor<p>I would like to introduce my new mini-project
<a href="http://xantorohara.github.io/led-matrix-editor">LED Matrix Editor</a> created for the Arduino community.</p>
<p>This is online tool for editing and creating animations for LED dot matrices.</p>
<p><img alt="LED Matrix Editor screenshot" class="blog-image" src="https://raw.githubusercontent.com/xantorohara/led-matrix-editor/master/resources/led-matrix-editor.png" /></p>
<p>It looks very simple, but it has some handy features:</p>
<ul>
<li>Toggle LEDs using a mouse</li>
<li>Toggle a whole row or column by clicking the appropriate matrix's index</li>
<li>Shift the matrix Up, Down, Left or Right via the single click</li>
<li>Invert or Clear matrix</li>
<li>Collect matrices in the bottom pane and then reorder them using the Drag-and-Drop</li>
<li>Update images as well as insert new or delete existing</li>
<li>Save images as a C code for Arduino</li>
<li>Use browsing history and save images as a link or bookmark, so you never lost your creations</li>
</ul>
<p>I hope you will be fun and happy using it.</p>
<video width="640" height="360" controls preload="auto" poster="https://raw.githubusercontent.com/xantorohara/led-matrix-editor/master/resources/MAH02147_960x540.jpg"><source src="https://raw.githubusercontent.com/xantorohara/led-matrix-editor/master/resources/MAH02147_960x540.mp4" type="video/mp4"></video>
<p>Assume you have a matrix (based on a board with MAX7219) like this:</p>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/2jmq72ZFa" target="_blank"><img src="https://github.com/xantorohara/led-matrix-editor/raw/master/resources/max7219-module.jpg"/><br/>LED matrix MAX7219</a></div>
<p>*This chip it is really cool and there is a good <a href="http://playground.arduino.cc/Main/LedControl#Source">LedControl</a> library for Arduino for this chip.</p>
<p>Then you have created an animation using the online editor, copied and pasted generated code to the Arduino IDE:</p>
<pre><code class="lang-c">#include <LedControl.h>
const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;
const uint64_t IMAGES[] = {
0x3e2222223e3e0808, 0x3e22223e3e2a0808, 0x3e223e3e2a2a0808, 0xbe3e3e2a2a2a0808,
0xbe223e3e2a2a0808, 0xbe22223e3e2a0808, 0xbe2222223e3e0808, 0xbe22223e3e2a0808,
0xbe223e3e2a2a0808, 0xbebe3e2a2a2a0808, 0xbea23e3e2a2a0808, 0xbea2223e3e2a0808,
0xbea222223e3e0808, 0xbea2223e3e2a0808, 0xbea23e3e2a2a0808, 0xbebebe2a2a2a0808,
0xbea2be3e2a2a0808, 0xbea2a23e3e2a0808, 0xbea2a2223e3e0808, 0xbea2a23e3e2a0808,
0xbea2be3e2a2a0808, 0xbebebeaa2a2a0808, 0xbea2bebe2a2a0808, 0xbea2a2be3e2a0808,
0xbea2a2a23e3e0808, 0xbea2a2be3e2a0808, 0xbea2bebe2a2a0808, 0xbebebeaaaa2a0808,
0xbea2bebeaa2a0808, 0xbea2a2bebe2a0808, 0xbea2a2a2be3e0808, 0xbea2a2bebe2a0808,
0xbea2bebeaa2a0808, 0xbebebeaaaaaa0808, 0xbea2bebeaaaa0808, 0xbea2a2bebeaa0808,
0xbea2a2a2bebe0808, 0xbea2a2a2a2be1c08, 0xbea2a2a2a2a21c1c, 0xbea2a2a2a222001c,
0xbea2a2a22222001c, 0xbea2a2222222001c, 0xbea222222222001c, 0xbe2222222222001c,
0x3e2222222222001c, 0x3e2222222222001c, 0x3e22222222221c1c, 0x3e222222223e1c08
};
const int IMAGES_LEN = sizeof(IMAGES) / sizeof(uint64_t);
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);
void setup() {
display.clearDisplay(0);
display.shutdown(0, false);
display.setIntensity(0, 10);
}
void displayImage(uint64_t image) {
for (int i = 0; i < 8; i++) {
byte row = (image >> i * 8) & 0xFF;
for (int j = 0; j < 8; j++) {
display.setLed(0, i, j, bitRead(row, j));
}
}
}
int i = 0;
void loop() {
displayImage(IMAGES[i]);
if (++i >= IMAGES_LEN ) {
i = 0;
}
delay(100);
}
</code></pre>
<p>Compile, upload and enjoy:</p>
<video width="640" height="360" controls preload="auto" poster="https://raw.githubusercontent.com/xantorohara/led-matrix-editor/master/resources/MAH02145_960x540.jpg"><source src="https://raw.githubusercontent.com/xantorohara/led-matrix-editor/master/resources/MAH02145_960x540.mp4" type="video/mp4"></video>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-15743048199583563122015-08-30T20:53:00.001+03:002015-08-30T21:38:01.941+03:00Arduino: manage 8-channel relay module via infrared remote control<p>Arduino allows us to do simple things in a simple way.</p>
<p>Pretty obvious desire - to control home electronics using the remote control:
manage lighting, doors remotely by pressing the buttons. It is really easy. You just need these components:
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/BuvvNJYBm" target="_blank"><img src="http://g02.a.alicdn.com/kf/HTB13t8nIXXXXXc9XFXXq6xXFXXXj/High-Quality-New-8-Channel-12V-Relay-Module-Shield-For-Arduino-UNO-2560-1280-ARM-PIC.jpg_220x220.jpg"/><br/>Relay module 8-channel </a></div><div class="blog-product"><a href="http://s.click.aliexpress.com/e/y7euzNnuZ" target="_blank"><img src="http://g03.a.alicdn.com/kf/HTB1O_r9IXXXXXaaXXXXq6xXFXXXc/ATMEGA-328P-MEGA328P-Uno-R3-with-USB-Cable-for-Arduino-Compatible.jpg_220x220.jpg"/><br/>Arduino Uno</a></div><div class="blog-product"><a href="http://s.click.aliexpress.com/e/Eu337IaYZ" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/32316258727_1/barterine-KY-022-Infrared-IR-Sensor-Receiver-Module-For-Arduino.jpg_220x220.jpg"/><br/>Infrared sensor</a></div></p>
<p>Connect all together:</p>
<p><img alt="Arduino, 8-channel relay, IR remote control" class="blog-image" src="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/photos/DSC02111.JPG" /></p>
<p>Upload the source code to the Arduino board:</p>
<pre><code class="lang-c">#include <IRremote.h>
const int IR_PIN = 2;
const int RELAY_PINS[8] = {12, 11, 10, 9, 8, 7, 6, 5};
int RELAY_STATES[8] = {LOW};
IRrecv irrecv(IR_PIN);
decode_results results;
void setup() {
irrecv.enableIRIn();
for (int i = 0; i < 8; i++) {
pinMode(RELAY_PINS[i], OUTPUT);
}
}
/**
* Decode IR code to numeric button 0-9
* Return pressed button number or -1
*/
int samsungDecode(unsigned long irValue) {
switch (irValue) {
case 0xE0E020DF:
return 1;
case 0xE0E0A05F:
return 2;
case 0xE0E0609F:
return 3;
case 0xE0E010EF:
return 4;
case 0xE0E0906F:
return 5;
case 0xE0E050AF:
return 6;
case 0xE0E030CF:
return 7;
case 0xE0E0B04F:
return 8;
case 0xE0E0708F:
return 9;
case 0xE0E08877:
return 0;
}
return -1;
}
/**
* Toggle single relay or switch ON/OFF all relays
*/
void action(int button) {
if (button > 0 && button < 9) {
//toggle single relay
int i = button - 1;
if (RELAY_STATES[i] == LOW) {
digitalWrite(RELAY_PINS[i], HIGH);
RELAY_STATES[i] = HIGH;
} else {
digitalWrite(RELAY_PINS[i], LOW);
RELAY_STATES[i] = LOW;
}
} else if (button == 9) {
//switch ON all relays
for (int i = 0; i < 8; i++) {
digitalWrite(RELAY_PINS[i], HIGH);
RELAY_STATES[i] = HIGH;
}
} else if (button == 0) {
//switch OFF all relays
for (int i = 0; i < 8; i++) {
digitalWrite(RELAY_PINS[i], LOW);
RELAY_STATES[i] = LOW;
}
}
}
int lastPressedButton = -1;
void loop() {
if (irrecv.decode(&results)) {
int button = samsungDecode(results.value);
if (button != lastPressedButton) {
lastPressedButton = button;
action(button);
}
irrecv.resume();
} else {
lastPressedButton = -1;
}
delay(250);
}
</code></pre>
<p>And enjoy by pressing buttons:</p>
<video width="640" height="360" controls preload="auto" poster="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/videos/MAH02116_960x540.jpg"><source src="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/videos/MAH02116_960x540.mp4" type="video/mp4"></video>
<p>Buttons 1-8 manage relays 1-8, button 9 switch on all relays, and button 0 switch all off.</p>
<p>The previous day I wrote the article <a href="/2015/08/arduino-scan-codes-remote-control.html">Arduino: scan codes from a remote control</a>. I have scanned codes for my Samsung remote control. So if you have another remote control, just scan your codes.</p>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com1tag:blogger.com,1999:blog-4306704057846428012.post-65644749267928761562015-08-29T20:45:00.001+03:002015-08-30T20:53:06.489+03:00Arduino: scan codes from a remote control<p>There are different types of infrared remote controls produced by different companies: for TV, DVD and other consumer electronics. As well all of them can be reused for Arduino using an infrared sensor.</p>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/Eu337IaYZ" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/32316258727_1/barterine-KY-022-Infrared-IR-Sensor-Receiver-Module-For-Arduino.jpg_220x220.jpg"/><br/>Infrared sensor</a></div>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/y7euzNnuZ" target="_blank"><img src="http://g03.a.alicdn.com/kf/HTB1O_r9IXXXXXaaXXXXq6xXFXXXc/ATMEGA-328P-MEGA328P-Uno-R3-with-USB-Cable-for-Arduino-Compatible.jpg_220x220.jpg"/><br/>Arduino Uno</a></div>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/bAeE6euJY" target="_blank"><img src="http://g03.a.alicdn.com/kf/HTB1KQXhJXXXXXX6XXXXq6xXFXXXm/New-Hot-Selling-New-Remote-Control-For-Samsung-AA59-00638A-3D-Smart-TV.jpg_220x220.jpg"/><br/>Samsung remote control</a></div>
<p>Different remote controls may have different sets of codes, so first you need to determine what code is sent by each button. It is simple.
Just connect IR sensor with Arduino:</p>
<p><img alt="Arduino Uno + IR sensor" class="blog-image" src="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/photos/DSC02102.JPG" /></p>
<p>Run this program:</p>
<pre><code class="lang-c">#include <IRremote.h>
const int IR_PIN = 10;
IRrecv irrecv(IR_PIN);
decode_results results;
void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
}
char chars[9] = {};
void loop() {
if (irrecv.decode(&results)) {
Serial.println(results.value, HEX);
irrecv.resume();
}
delay(100);
}
</code></pre>
<p><sub>*It uses <a href="https://github.com/z3t0/Arduino-IRremote">IRremote library</a>.</sub></p>
<p>Open serial monitor, press some buttons on the remote control and see the output:</p>
<p><img alt="Serial print scanned codes" class="blog-image" src="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/images/serial-monitor-scan-ir-codes.png" /></p>
<p>Program prints codes for pressed buttons. For example, a remote control from the Samsung SmartTV sends these codes for numeric buttons:</p>
<ul>
<li>E0E020DF 1</li>
<li>E0E0A05F 2</li>
<li>E0E0609F 3</li>
<li>E0E010EF 4</li>
<li>E0E0906F 5</li>
<li>E0E050AF 6</li>
<li>E0E030CF 7</li>
<li>E0E0B04F 8</li>
<li>E0E0708F 9</li>
<li>E0E08877 0</li>
</ul>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-5058769064537699852015-08-29T19:54:00.000+03:002015-08-30T20:52:41.397+03:00Arduino: print sensor value on the LED display<p>It is pretty simple to print a value from an analog sensor on the LED display.</p>
<p>For example from a light sensor like here:</p>
<p><img alt="Output light sensor value to led display" class="blog-image" src="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/photos/DSC02092.JPG" /></p>
<p>and when the sensor is out of light:</p>
<p><img alt="Output light sensor value to led display (closed)" class="blog-image" src="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/photos/DSC02093.JPG" /></p>
<p>Electronic components from the scheme above:</p>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/m27iY3B2j" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/1909207905/Microcontroller-Board-Compatible-with-Arduino-Nano.jpg_220x220.jpg"/><br/>Arduino Nano</a></div>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/eAEyNBqBu" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/1449630475_1/MAX7219-Red-Module-8-Digit-7-Segment-Digital-LED-Display-Tube-For-Arduino-MCU.jpg_220x220.jpg"/><br/>Led display MAX7219</a></div>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/F27EIMJuR" target="_blank"><img src="http://g02.a.alicdn.com/kf/HTB1K7IaIFXXXXbjXVXXq6xXFXXXv/LM393-Optical-Sensitive-Resistance-Sensor-Module-Photosensitive-Sensor-for-arduino-3-pin-SG060-SZ.jpg_220x220.jpg"/><br/>Light sensor</a></div>
<p>LED display is connected with Arduino via these 5 pins:</p>
<ul>
<li>DIN - data in</li>
<li>CS - chip select</li>
<li>CLK - clock pulse source</li>
<li>GND</li>
<li>5 V</li>
</ul>
<p>DIN, CS and CLK are connected with Arduino via digital pins 7, 6 and 5.</p>
<p>Light sensor has 3 pins:</p>
<ul>
<li>GND</li>
<li>5V</li>
<li>Signal</li>
</ul>
<p>where signal pin is connected with Arduino via the analog pin №1.</p>
<p>This program reads values from the sensor 10 times per second and displays the averaged result:</p>
<pre><code class="lang-c">#include <LedControl.h>
const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;
const int SENSOR_PIN = 1;
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);
void setup() {
display.clearDisplay(0);
display.shutdown(0, false);
display.setIntensity(0, 10);
}
void displayNumber(int number) {
display.clearDisplay(0);
for (int i = 0; i < 8; i++) {
int digit = number % 10;
number /= 10;
display.setDigit(0, i, digit, false);
if (number == 0) {
break;
}
}
}
void loop() {
int value = 0;
for (int i = 0; i < 10; i++) {
value += analogRead(SENSOR_PIN);
delay(100);
}
value /= 10;
displayNumber(value);
}
</code></pre>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-22798043922351531872015-07-22T23:15:00.001+03:002015-08-30T20:52:02.541+03:00Arduino: output multiple numbers to a digital LED display<p>In the previous
<a href="/2015/07/arduino-output-number-to-8-digits-led-display-max7219.html">article</a>
I was describing how to output number into this LED display:
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/eAEyNBqBu" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/1449630475_1/MAX7219-Red-Module-8-Digit-7-Segment-Digital-LED-Display-Tube-For-Arduino-MCU.jpg_220x220.jpg"/><br/>Led display MAX7219</a></div></p>
<p>But it is much interesting to display multiple numbers on a single LED module (for example: temperature and moisture or distance and time). It is pretty simple to write it in C.</p>
<p>Like in a previous example DIN, CS and CLK are connected with arduino through these pins: 7, 6 and 5.
Here is the working prototype:</p>
<p><img alt="Output 2 numbers to led display" class="blog-image" src="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/photos/DSC02096.JPG" /></p>
<p>In this example are implemented two counters: 2-digits, and 5-digits.
The first counter increments from 0 to 99, and then resets on reaching the maximum values.
The second - reduces from 99999 to 0, and resets after the zero.
In each cycle a digital display shows both numbers at the same time, with an empty place as a separator between them.</p>
<p>Code sample:</p>
<pre><code class="lang-c">#include <LedControl.h>
const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);
void setup() {
display.clearDisplay(0);
display.shutdown(0, false);
display.setIntensity(0, 10);
}
void displayString(const char *chars8) {
display.clearDisplay(0);
for (int i = 0; i < 8 && chars8[i] != 0; i++) {
display.setChar(0, 7 - i, chars8[i], false);
}
}
int counter1 = 0;
long counter2 = 99999;
char chars[9] = {};
void loop() {
snprintf(chars, 9, "%-2d %5ld", counter1, counter2);
displayString(chars);
counter1++;
counter2--;
if (counter1 > 99) {
counter1 = 0;
}
if (counter2 < 0) {
counter2 = 99999;
}
delay(250);
}
</code></pre>
<p>In this example two numbers are packed into the char array and then displayed via the <code>displayString()</code> function.
I use <code>snprintf()</code> function for this; it is much safe then <code>sprintf()</code>.</p>
<p>The first number is aligned on the left edge of the display, the second - on the right.</p>
<p>This code requires <a href="http://playground.arduino.cc/Main/LedControl#Source">LedControl library</a>.</p>
<p>Set of components used in this example:
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/eAEyNBqBu" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/1449630475_1/MAX7219-Red-Module-8-Digit-7-Segment-Digital-LED-Display-Tube-For-Arduino-MCU.jpg_220x220.jpg"/><br/>Led display MAX7219</a></div>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/m27iY3B2j" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/1909207905/Microcontroller-Board-Compatible-with-Arduino-Nano.jpg_220x220.jpg"/><br/>Arduino Nano</a></div>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/yjImm6uRF" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/32293754425/R1B1-400-Points-Solderless-Bread-Board-Breadboard-PCB-Test-Board.jpg_220x220.jpg"/><br/>Breadboard</a></div></p>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-12612519834942086022015-07-20T23:50:00.001+03:002015-08-30T20:52:19.127+03:00Arduino: output number into digital LED display MAX7219<p>There are some LED modules for Arduino to display numbers.</p>
<p>For example, this LED display with 8-digits based on the chip MAX7219:
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/eAEyNBqBu" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/1449630475_1/MAX7219-Red-Module-8-Digit-7-Segment-Digital-LED-Display-Tube-For-Arduino-MCU.jpg_220x220.jpg"/><br/>Led display MAX7219</a></div></p>
<p>It connects to the Arduino board via five pins:</p>
<ol>
<li>DIN - data in</li>
<li>CS - chip select</li>
<li>CLK - clock pulse source</li>
<li>GND</li>
<li>5 V</li>
</ol>
<p>In this example all elements are connected in this way:</p>
<p><img alt="Output number to led display" class="blog-image" src="https://dl.dropboxusercontent.com/u/5036450/arduino-howto/photos/DSC02103.JPG" /></p>
<p>Here DIN, CS and CLK are connected with pins 7, 6 and 5.</p>
<p>Arduino site has a big <em>LedControl</em> article related to control over the LED matrix. But it doesn't contain a sample that shows how to output whole number.</p>
<p>The code below implements a simple counter, which increases its value once per second and displays it on a digital display:</p>
<pre><code class="lang-c">#include <LedControl.h>
const int DIN_PIN = 7;
const int CS_PIN = 6;
const int CLK_PIN = 5;
LedControl display = LedControl(DIN_PIN, CLK_PIN, CS_PIN);
void setup() {
display.clearDisplay(0);
display.shutdown(0, false);
display.setIntensity(0, 10);
}
void displayString(const char *chars8) {
display.clearDisplay(0);
for (int i = 0; i < 8 && chars8[i] != 0; i++) {
display.setChar(0, 7 - i, chars8[i], false);
}
}
int counter1 = 0;
long counter2 = 99999;
char chars[9] = {};
void loop() {
snprintf(chars, 9, "%-2d %5ld", counter1, counter2);
displayString(chars);
counter1++;
counter2--;
if (counter1 > 99) {
counter1 = 0;
}
if (counter2 < 0) {
counter2 = 99999;
}
delay(250);
}
</code></pre>
<p>In this code I use <code>displayNumber()</code> function, that writes value for each decimal digit into the appropriate LED segment.</p>
<p>This code requires <a href="http://playground.arduino.cc/Main/LedControl#Source">LedControl library</a>.</p>
<p>Electronic components used in this example:
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/eAEyNBqBu" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/1449630475_1/MAX7219-Red-Module-8-Digit-7-Segment-Digital-LED-Display-Tube-For-Arduino-MCU.jpg_220x220.jpg"/><br/>Led display MAX7219</a></div>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/m27iY3B2j" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/1909207905/Microcontroller-Board-Compatible-with-Arduino-Nano.jpg_220x220.jpg"/><br/>Arduino Nano</a></div>
<div class="blog-product"><a href="http://s.click.aliexpress.com/e/yjImm6uRF" target="_blank"><img src="http://i01.i.aliimg.com/wsphoto/v0/32293754425/R1B1-400-Points-Solderless-Bread-Board-Breadboard-PCB-Test-Board.jpg_220x220.jpg"/><br/>Breadboard</a></div></p>Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-4500787915022403042015-02-01T01:19:00.000+03:002018-07-15T10:22:05.108+03:00How to open sas7bdat fileI found <a href="https://xantorohara.github.io/rocket-table/">Rocket Table</a> application for this purpose.
It doesn't require any SAS software, it's free and easy to use.
<br />
SAS Table Explorer allows you to open file in the .sas7bdat format and shows it as a table.
<br />
<br />
Main features of this application are:<br />
<ul>
<li>Search over the whole dataset, or by specific columns</li>
<li>Highlight search results</li>
<li>Wildcard search</li>
<li>Truncate the analyzed dataset (to matched or selected rows)</li>
</ul>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7xDzS8xQ6-HXjznw1FZhf7fOvYtNupKKUT90AHr6GCb1PmnHnnVjBs6xMwS_bZPXfOjYOKsa0TgoBfAZn4zG5bOQyrcS3stT8sImsMcWv8AwH7WVG9RFx6laDbMsvg1ewNkTTits6lc_P/s1600/screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="578" data-original-width="976" height="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7xDzS8xQ6-HXjznw1FZhf7fOvYtNupKKUT90AHr6GCb1PmnHnnVjBs6xMwS_bZPXfOjYOKsa0TgoBfAZn4zG5bOQyrcS3stT8sImsMcWv8AwH7WVG9RFx6laDbMsvg1ewNkTTits6lc_P/s320/screenshot.png" width="320" /></a></div>
<br />
Anyway this is the most compact tool for opening sas files.Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-25357572983596548642015-01-07T00:47:00.000+03:002015-01-07T00:50:09.257+03:00How to close Java splash image after the application startsThere is a very easy way to get Splash screen in Java application.<br />
With a "-splash:imagepath" command line parameter, or with "SplashScreen-Image: imagepath" manifest parameter.<br />
<br />
But when an application is started, Java still shows this image (below the application layer, but it visible when you switching between the applications), until the application is finished. Strange behavior, but it is possible to close this kind of splash screen.<br />
<br />
With these lines of code:<br/>
<pre>
import java.awt.SplashScreen;
...
SplashScreen splashScreen = SplashScreen.getSplashScreen();
if (splashScreen != null) {
splashScreen.close();
}
</pre>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-91541764454890447152015-01-07T00:25:00.000+03:002015-01-07T00:25:32.066+03:00How to create a file extension association with the program in WindowsAssume that you have a program named "table-explorer.exe".<br />
And you want to open all ".csv" and ".sas7bdat" files using this program by default in Windows.<br />
<br />
First you need to create a file extension association with the program via these commands:<br />
<pre></pre>
<br />
reg add HKCU\SOFTWARE\Classes\.csv /d "table-explorer" /f<br />
reg add HKCU\SOFTWARE\Classes\.sas7bdat /d "table-explorer" /f<br />
<br />
<br />
And then register the application:<br />
<pre></pre>
<br />
reg add HKCU\SOFTWARE\Classes\table-explorer\shell\open\command /d "\"C:\Path\to\table-explorer.exe\"" /f<br />
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0tag:blogger.com,1999:blog-4306704057846428012.post-69438989902991969742015-01-06T23:51:00.000+03:002015-01-06T23:54:58.976+03:00How to bind hotkeys in Java FXIt is possible to create global keyboard shortcuts using a code like this:
<pre>
import static javafx.scene.input.KeyCombination.keyCombination;
...
private void initHotkeys() {
ObservableMap<KeyCombination, Runnable> accelerators = stage.getScene().getAccelerators();
accelerators.put(keyCombination("Alt+S"), searchTextField::requestFocus);
accelerators.put(keyCombination("Alt+C"), columnsTextField::requestFocus);
accelerators.put(keyCombination("Alt+O"), openFileButton::fire);
accelerators.put(keyCombination("Alt+E"), exportButton::fire);
accelerators.put(keyCombination("Alt+T"), truncateButton::fire);
accelerators.put(keyCombination("Alt+H"), () -> filterChoiceBox.setValue(MATCH_HIGHLIGHT));
accelerators.put(keyCombination("Alt+F"), () -> filterChoiceBox.setValue(MATCH_FILTER));
accelerators.put(keyCombination("Alt+U"), () -> filterChoiceBox.setValue(MATCH_FILTER_UNIQUE));
accelerators.put(keyCombination("Alt+D"), () -> {
//todo some debug action
});
}
</pre>
Xantoroharahttp://www.blogger.com/profile/05302201977749671284noreply@blogger.com0