し、集団訴訟て、

投稿日:

 そんなもん、知るかあほんだらw

 これ全部読んで理解するのに何時間いるっちゅーねん(笑)。


マイクロソフト ソフトウェア ライセンス条項
WINDOWS オペレーティング システム
お客様の居住地 (またはお客様の会社の主たる業務地) が米国内である場合、第 10 条に記載されている拘束力のある仲裁と集団訴訟の権利放棄について内容を注意深くお読みください第 10 条は、紛争を解決する方法に影響を及ぼします
マイクロソフトをお選びいただきありがとうございます
お客様が本 Windows ソフトウェアを取得された方法に応じて、本文は、(i) お客様のデバイスと共に本ソフトウェアを頒布するデバイス製造業者またはソフトウェア インストール業者とお客様の間で、または (ii) お客様が本ソフトウェアを小売業者から取得された場合は、お客様と Microsoft Corporation (またはお客様の所在地もしくは会社の場合は主たる業務地に応じたその関連会社。以下、「マイクロソフト」といいます) の間で、締結されるライセンス契約書です。マイクロソフトまたはそのいずれかの関連会社が生産したデバイスについてはマイクロソフトがデバイス製造業者であり、お客様が本ソフトウェアをマイクロソフトから直接取得された場合はマイクロソフトが小売業者となります。
本ライセンス条項には、本 Windows ソフトウェアを使用するお客様の権利および条件を規定しています。すべての条項が重要であり、一体となってお客様に適用される本ライセンス条項を形成するため、本ソフトウェアに付属する、追加ライセンス条項およびリンク先の条項を含む本ライセンス条項全文を確認してください。お客様は、ブラウザー ウィンドウに (aka.ms/) リンクを貼り付けることで、リンク先の条項を確認できます。
お客様は、本ライセンス条項に同意するか、または本ソフトウェアを使用することにより、これらすべての条項に同意し、ライセンス認証中およびお客様が本ソフトウェアを使用する際に第 3 条に記載されているプライバシーに関する声明に従って特定の情報が送信されることに同意するものとします。お客様がこれらの条項に同意せず、またこれらの条項を遵守しない場合、本ソフトウェアまたはその機能を使用することはできません。この場合、デバイス製造業者もしくはインストール業者に、または本ソフトウェアを直接購入された場合はご利用の小売業者に、問い合わせて、返品方針を確認してください。この方針に基づいて本ソフトウェアまたはデバイスを返品し、お支払いいただいた金額の払い戻しを受けられる場合があります。お客様は、この方針に従わなければなりません。この方針により、お客様は、払い戻しを受けるために本ソフトウェアと共に、本ソフトウェアがインストールされているデバイス全体を返品することが求められる場合があります。
1.	概要。
a.	適用対象。本ライセンス条項は、お客様のデバイスにプレインストールされている、または小売業者から取得してお客様がインストールした本 Windows ソフトウェア、お客様が本ソフトウェアを受領したときのメディア (存在する場合)、本ソフトウェアに含まれるフォント、アイコン、画像、または音声ファイル、および本ソフトウェアに対するマイクロソフトの更新プログラム、アップグレード、追加ソフトウェア、またはサービスに適用されます。ただし、これらにその他の条項が付属している場合は、その限りではありません。マイクロソフトが開発し、Windows に含まれてその一部となっている機能 (連絡先、ミュージック、フォト、ニュースなど) を提供する Windows アプリケーションにも適用されます。本ライセンス条項にお客様のデバイスで利用できない機能またはサービスに関する条項が含まれている場合、当該条項は適用されません。
b.	追加条項。お客様のデバイスの機能、構成内容、および使用方法に応じて、お客様による特定の機能、サービス、およびアプリケーションの使用にマイクロソフトおよび第三者の追加条項が適用される場合があります。当該条項を必ずお読みください。
(i)	一部の Windows アプリケーションは、オンライン サービスへのアクセス ポイントを提供するか、オンライン サービスに依存しています。そのため、これらのサービスの利用には、(aka.ms/msa) に掲載されている Microsoft サービス規約などの別途の条項およびプライバシー ポリシーが適用される場合があります。お客様は、これらの条項およびポリシーを、サービス使用条件またはアプリケーションの設定 (該当する場合) を参照することで確認できます。これらのサービスを利用できない地域がある場合もあります。
(ii)	マイクロソフト、製造業者、またはインストール業者は、追加のアプリケーションを含めることがあります。かかるアプリケーションには、別途のライセンス条項およびプライバシー ポリシーが適用されます。
(iii)	本ソフトウェアには、Adobe Systems Incorporated の条項 (aka.ms/adobeflash) に基づいてライセンスされる Adobe Flash Player が含まれています。Adobe および Flash は、Adobe Systems Incorporated の米国およびその他の国における登録商標または商標です。
(iv)	本ソフトウェアには、本ライセンス条項または第三者独自の条項に基づいて、お客様にライセンスされる第三者のプログラムが含まれていることがあります。第三者のプログラムにライセンス条項、通知、および確認事項がある場合は、(aka.ms/thirdpartynotices) で確認できます。
(v)	Word、Excel、PowerPoint、および OneNote が Windows に同梱されている場合、これらのアプリケーションは、お客様による個人的かつ非商業的使用のためにライセンスされます。ただし、お客様が別途の契約に基づく商用使用権を有している場合はその限りではありません。
2.	インストールおよび使用権。
a.	ライセンス。本ソフトウェアは使用許諾されるものであり、販売されるものではありません。本ライセンス条項に基づいて、マイクロソフトは、一度に 1 人のユーザーが使用することを目的として、お客様のデバイス (ライセンスを取得したデバイス) に本ソフトウェアの 1 つのインスタンスをインストールして実行する権利を許諾します。ただし、お客様が本ライセンス条項のすべての条項を遵守することを条件とします。マイクロソフトまたは正規マイクロソフト販売代理店から取得した本ソフトウェアを使用して非正規のソフトウェアを更新またはアップグレードしても、元のバージョンまたは更新もしくはアップグレード後のバージョンは正規のソフトウェアにはならず、この場合、お客様は本ソフトウェアを使用するライセンスを取得していないことになります。
b.	デバイス。本ライセンス条項では、「デバイス」とは、内部記憶装置を搭載して本ソフトウェアを実行することのできるハードウェア システム (物理的システムまたは仮想システム) を意味します。ハードウェアのパーティションまたはブレードはデバイスと見なされます。
c.	制限。製造業者またはインストール業者、およびマイクロソフトは、本ライセンス条項において明示的に許諾されていない権利 (知的財産に関する法律に基づく権利など) をすべて留保します。たとえば、このライセンスは、次の行為に関してお客様にいかなる権利も与えるものではなく、お客様は次の行為を行うことはできません。
(i)	本ソフトウェアの機能を分離して使用または仮想化すること。
(ii)	本ソフトウェアを公開、複製 (許可されているバックアップ用の複製を除きます)、レンタル、リース、または貸与すること。
(iii)	本ソフトウェアを譲渡すること (本ライセンス条項で許諾されている場合を除きます)。
(iv)	本ソフトウェアの技術的な制限を回避すること。
(v)	本ソフトウェアをサーバー ソフトウェアとして使用することもしくは商業的ホスティング用に使用すること、本ソフトウェアをネットワークを介して複数のユーザーが同時に使用できるようにすること、本ソフトウェアをサーバーにインストールしてユーザーがリモート アクセスできるようにすること、または本ソフトウェアをリモート ユーザーのみが使用する目的でデバイスにインストールすること。
(vi)	本ソフトウェアをリバース エンジニアリング、逆コンパイル、もしくは逆アセンブルすること、またはこれらの行為を試みること。ただし、適用される法令、または本ソフトウェアにオープンソース コンポーネントが含まれる場合において当該コンポーネントの使用に適用されるライセンス条項により上記の行為が認められている場合には、当該範囲に限って上記の行為が認められます。
(vii)	インターネット ベースの機能を使用している場合、第三者によるこれらの機能の使用を妨げる可能性のある方法で、またはサービス、データ、アカウント、もしくはネットワークに不正な方法でアクセスを試みるために、これらの機能を使用すること。
d.	複数使用のシナリオ。
(i)	複数のバージョン。複数のバージョン (例: 32 ビット版と 64 ビット版) が提供される本ソフトウェアを取得した場合、お客様が同時にインストールしてライセンス認証できるのはそのいずれか 1 つのバージョンのみです。
(ii)	複数接続またはプールされた接続。マルチプレキシングもしくは接続をプールするために、または本ソフトウェアにアクセスもしくはこれを使用するデバイスもしくはユーザーの数を減らすためにハードウェアもしくはソフトウェアを使用しても、お客様に必要なライセンスの数が減ることはありません。お客様は、使用している本ソフトウェアのインスタンスすべてのライセンスを取得している場合にのみ、これらのハードウェアまたはソフトウェアを使用できます。
(iii)	デバイスの接続。お客様は、ライセンスを取得したデバイスでファイル サービス、印刷サービス、インターネット インフォメーション サービス、インターネット接続の共有およびテレフォニー サービスを利用することを目的として、ライセンスを取得したデバイスにインストールされた本ソフトウェアに対し、最大 20 台の他のデバイスからの接続を許可することができます。お客様は、任意の数のデバイスに、デバイス間でデータを同期するために、ライセンスを取得したデバイス上の本ソフトウェアにアクセスすることを許可することができます。ただし、本項は、お客様がこれらの他のデバイスに本ソフトウェアをインストールしたり、本ソフトウェアの主要な機能 (本項に記載する機能を除きます) を当該デバイス上で使用したりする権利を有することを意味するものではありません。
(iv)	仮想化された環境における使用。このライセンスでは、物理的デバイスであるか仮想デバイスであるかにかかわらず、1 台のデバイスに本ソフトウェアの 1 つのインスタンスのみをインストールして使用することが許諾されます。お客様は、複数の仮想デバイス上で本ソフトウェアを使用する場合、インスタンスごとに別途ライセンスを取得しなければなりません。
(v)	リモート アクセス。お客様は、90 日間に 1 回を上限として、ライセンスを取得したデバイスを物理的に使用する 1 名のユーザーをライセンス ユーザーとして指定することができます。ライセンス ユーザーは、リモート アクセス テクノロジを使用して他のデバイスから、ライセンスを取得したデバイスにアクセスすることができます。他のユーザーは、かかるアクセスとは異なるときにリモート アクセス テクノロジを使用して他のデバイスから、ライセンスを取得したデバイスにアクセスできますが、当該他のデバイスにおいて本ソフトウェアと同等以上のエディションを実行するライセンスが別途取得されている場合に限ります。
(vi)	リモート アシスタンス。お客様は、リモート アシスタンス テクノロジを使用して、本ソフトウェアの追加ライセンスを取得せずに、アクティブなセッションを共有できます。リモート アシスタンスを使用すると、通常は問題を修正するために、あるユーザーが別のユーザーのコンピューターに直接接続することができます。
e.	バックアップ用の複製。お客様は、バックアップ目的で本ソフトウェアの複製 1 部を作成できます。また、本ソフトウェアをスタンドアロン ソフトウェアとして取得した場合は、以下の第 4 条に規定するとおり、そのバックアップ用の複製を使用して、本ソフトウェアを移管することができます。
3.	プライバシー、データの使用への同意。お客様のプライバシーは、当社にとって重要です。本ソフトウェアの一部の機能については、当該機能を使用する際に情報が送受信されます。これらの機能の多くは、ユーザー インターフェイスで無効にするか、使用しないように選択することができます。お客様は、本ライセンス条項に同意し、本ソフトウェアを使用することで、マイクロソフトが、Microsoft プライバシーに関する声明の記載 (aka.ms/privacy)、および本ソフトウェアの機能と関連付けられているユーザー インターフェイスの記載に従って、情報を収集、使用、および開示できることに同意します。
4.	譲渡。本条の規定は、お客様がドイツまたは本サイト (aka.ms/transfer) に記載されているいずれかの国の消費者として本ソフトウェアを取得された場合には適用されません。その場合、本ソフトウェアの第三者への譲渡および本ソフトウェアを使用する権利については、適用される法令に従わなければなりません。
a.	デバイスにプレインストールされたソフトウェア。お客様は、デバイスにプレインストールされた本ソフトウェアを取得した場合 (およびデバイスにプレインストールされたソフトウェアからアップグレードした場合)、ライセンスを取得したデバイスと共にのみ、本ソフトウェアを使用するライセンスを別のユーザーに直接譲渡することができます。お客様は、本ソフトウェア、およびデバイスと共に提供された場合は、プロダクト キーを含む正規の Windows ラベルを含めて譲渡しなければなりません。許諾された譲渡を行う前に、本ソフトウェアの譲受者は本ライセンス条項が譲渡および本ソフトウェアの使用に適用されることに同意しなければなりません。
b.	スタンドアロン ソフトウェア。お客様は、本ソフトウェアをスタンドアロン ソフトウェアとして取得した場合 (およびスタンドアロン ソフトウェアとして取得したソフトウェアからアップグレードした場合)、お客様が所有する他のデバイスに本ソフトウェアを移管することができます。また、(i) お客様が本ソフトウェアの最初のライセンス ユーザーであり、また、(ii) 新しいユーザーが本ライセンス条項の条件に同意すれば、本ソフトウェアをそのユーザーが所有するデバイスに移管できます。お客様は、本ソフトウェアを移管するために、当社がお客様に作成を許可したバックアップ用の複製、または本ソフトウェアを収録したメディアを使用することができます。お客様が本ソフトウェアを新しいデバイスに移管する場合は必ず、本ソフトウェアを以前のデバイスからアンインストールしなければなりません。デバイス間でライセンスを共有する目的で本ソフトウェアを移管することはできません。
5.	許可されたソフトウェアおよびライセンス認証。お客様は、適切にライセンスを取得しており、本ソフトウェアが正規のプロダクト キーまたはその他の許可された方法で適切にライセンス認証されている場合に限り、本ソフトウェアを使用することが許可されます。お客様が本ソフトウェアの使用中にインターネットに接続したときに、本ソフトウェアによってマイクロソフトまたはその関連会社への問い合わせが自動的に行われ、本ソフトウェアが正規のものであることが確認され、そのライセンスがライセンスを取得したデバイスに関連付けられます。本ソフトウェアのライセンス認証は、インターネットまたは電話により、手動で行うこともできます。いずれの場合も、一定の情報が送信され、インターネット、電話、および SMS サービスの料金が発生することがあります。本ソフトウェアでは、ライセンス認証 (またはお客様のデバイスのコンポーネントを変更すると必要になる場合があるライセンス再認証) の際に、本ソフトウェアのインストール済みのインスタンスが偽造品であるか、ライセンスが適切に取得されていないか、不正な変更が含まれているか、が確認されることがあります。ライセンス認証に失敗した場合、改変されたマイクロソフト ソフトウェアを正規のマイクロソフト ソフトウェアに置き換えることで本ソフトウェアの修復が試みられます。また、本ソフトウェアの適切なライセンスを取得するよう求める通知がお客様に表示されることがあります。ライセンス認証を無視または回避することは、禁止されています。お客様のソフトウェアが正規のものであるかどうか、およびお客様が適切にライセンスを取得しているかどうかを確認するには、(aka.ms/genuine) をご参照ください。一定の更新プログラム、サポート、およびその他のサービスは、正規のマイクロソフト ソフトウェアのユーザーにのみ提供される場合があります。
6.	更新プログラム。本ソフトウェアでは、システムおよびアプリケーションの更新プログラムが定期的に確認され、自動的にダウンロードおよびインストールされます。お客様は、マイクロソフトまたは正規の提供元からのみ更新プログラムを取得できます。マイクロソフトは、当該更新プログラムをお客様に提供するために、お客様のシステムを更新する必要がある場合があります。お客様は、本ライセンス条項に同意することにより、追加通知なくこのような種類の自動更新プログラムを受け取ることに同意するものとします。
7.	ダウングレード権。お客様は、製造業者またはインストール業者から Windows の Professional バージョンがプレインストールされているデバイスを取得した場合、Windows 8.1 Pro または Windows 7 Professional バージョンを使用できますが、マイクロソフトが、(aka.ms/windowslifecycle) に規定されているとおり、かかる旧バージョンのサポートを提供している期間に限ります。本ライセンス条項は旧バージョンの使用に対しても適用されます。旧バージョンに異なるコンポーネントが含まれている場合、お客様によるかかるコンポーネントの使用については、旧バージョンに付属するライセンス条項の該当する条件が適用されます。製造業者もしくはインストール業者、またはマイクロソフトは、旧バージョンの本ソフトウェアをお客様に提供する義務を負いません。お客様は、旧バージョンを別途取得しなければならず、その際に料金が請求されることがあります。お客様は、いつでも旧バージョンを、最初に取得したバージョンに置き換えることができます。
8.	地理的制約と輸出規制。お客様による本ソフトウェアの使用が特定の地域に制限されている場合、お客様はその地域でのみ本ソフトウェアのライセンス認証を行うことができます。また、お客様は、本ソフトウェアに適用されるすべての国内法および国際法 (輸出対象国、エンド ユーザーおよびエンド ユーザーによる使用に関する制限を含みます) を遵守しなければなりません。地理的制約および輸出規制の詳細については、(aka.ms/georestrict) および (aka.ms/exporting) をご参照ください。
9.	サポートおよび払い戻し手続き。
a.	デバイスにプレインストールされたソフトウェアの場合。ソフトウェア全般のサポート オプションについては、デバイス製造業者またはインストール業者にお問い合わせください。その際、本ソフトウェアと共に提供されるサポート番号をお知らせください。更新プログラムおよび追加ソフトウェアをマイクロソフトから直接取得した場合、適切にライセンスを取得したソフトウェアについて、マイクロソフトから限定サポート サービスが提供されることがあります。詳細については、(aka.ms/mssupport) をご参照ください。お客様が払い戻しを要求する場合、製造業者またはインストール業者に問い合わせて、返金方針を確認してください。お客様は、この方針に従わなければなりません。この方針により、お客様は、払い戻しを受けるために本ソフトウェアと共に、本ソフトウェアがインストールされているデバイス全体を返品することが求められる場合があります。
b.	小売業者から取得したソフトウェアの場合。マイクロソフトでは、(aka.ms/mssupport) の規定に従い、適切にライセンスを取得したソフトウェアについて、限定されたサポート サービスを提供します。お客様が本ソフトウェアを小売業者から購入しており、要求している払い戻しを本ソフトウェアの購入店から受けられない場合は、マイクロソフトにマイクロソフトの返金方針についてお問い合わせください。(aka.ms/msoffices) をご覧になるか、北米では、(800) MICROSOFT までご連絡いただくか、または (aka.ms/nareturns) をご参照ください。
10.	お客様の所在地 (または会社の場合は主たる業務地) が米国内である場合の拘束力のある仲裁と集団訴訟の権利放棄。
当社は紛争が発生しないことを願っています。ただし、紛争が発生した場合、お客様および当社は、60 日間、解決に向けて非公式に努力することに同意するものとします。解決できなかった場合、お客様および当社は、連邦仲裁法 (以下「FAA」といいます) に準拠した、米国仲裁協会 (以下「AAA」といいます) による拘束力のある個別の仲裁によって解決することに同意し、裁判官または陪審員による裁判所への提訴を行わないものとします。この場合、中立的な仲裁人が決定を下し、仲裁人の決定は、FAA に基づく限定された上訴権を除き、最終的なものとなります。集団訴訟、集団仲裁、司法長官による民事訴訟、およびいずれかの当事者が代表者として提起するその他の訴訟は許可されません。両当事者の同意なしに、個別の訴訟を併合することも許可されません。「当社」には、マイクロソフト、デバイス製造業者、およびソフトウェア インストール業者が含まれます。
a.	紛争は 知的財産権を除くすべてを対象とすること。「紛争」という用語は、可能な限り広い意味で使用します。紛争には、契約、保証、不法行為、制定法、法令、規制を含むあらゆる法理に基づく、お客様と製造業者もしくはインストール業者の間、またはお客様とマイクロソフトの間における、本ソフトウェア、その対価、または本ライセンス条項に関するすべての請求または紛争が含まれます。ただし、お客様、お客様のライセンサー、当社、または当社のライセンサーの知的財産権の強制または有効性に関連する紛争を除きます。
b.	まず紛争通知を郵送すること。紛争が発生し、当社のカスタマー サービス担当者が解決できなかった場合、紛争通知を米国郵便で製造業者またはインストール業者の法務部門宛てに送付します。お客様がマイクロソフトとの紛争を提起する場合、郵便にて Microsoft Corporation (ATTN: LCA ARBITRATION, One Microsoft Way, Redmond, WA 98052-6399) まで送付してください。その際、お客様の名前、住所、連絡方法、問題の内容、および要求事項をお知らせください。紛争通知フォームは、(aka.ms/disputeform) から入手できます。当社も、お客様との紛争を提起する場合、同様に通知を送付します。紛争が解決せずに 60 日経過した場合、お客様または当社は仲裁を開始することができます。
c.	少額裁判所の選択。お客様は、少額裁判所の要件を満たしている場合、紛争通知を郵送する代わりに、お客様の住所地 (もしくは会社の場合は主たる業務地) またはお客様とマイクロソフトの間の紛争である場合は米国ワシントン州キング郡の少額裁判所でも、当社を提訴できます。紛争通知を郵送して当社が解決に向けて努力する 60 日間の猶予をいただけると幸いですが、お客様は、少額裁判所に提訴する前に、紛争通知を郵送する必要はありません。
d.	仲裁手続。すべての仲裁は、AAA が、その商事仲裁規則 (ただし、お客様が個人であり、本ソフトウェアを個人的にもしくは家庭で使用する場合、または、お客様が個人であるか本ソフトウェアをどのように使用するかにかかわらず 75,000 米ドル以下の紛争の場合は、AAA の消費者仲裁規則) に基づいて実施します。詳細については、(aka.ms/adr) を参照するか、1-800-778-7879 まで電話でお問い合わせください。仲裁を開始するには、(aka.ms/arbitration) で入手可能な仲裁請求用紙を AAA に提出し、その写しを製造業者もしくはインストール業者 (またはお客様とマイクロソフトとの間の紛争である場合はマイクロソフト) に郵送します。25,000 米ドル以下の紛争では、仲裁人が対面による期日を開く正当な理由があると判断した場合を除き、すべての期日は電話で行われます。対面による期日は、お客様の住所地 (もしくは会社の場合は主たる業務地) または当社の主たる業務地 (お客様とマイクロソフトの間の紛争である場合は米国ワシントン州キング郡) のいずれかお客様が選択する場所で実施するものとします。仲裁人は、裁判所と同じ賠償をお客様個人に認めることができます。仲裁人は、差し止め命令による救済または宣言的救済をお客様に対して個別に、お客様の個別の請求に応じるために、認めることができます。
e.	仲裁手数料および支払い。
(i)	75,000 米ドル以下の紛争。製造業者もしくはインストール業者 (またはお客様とマイクロソフトの間の紛争である場合はマイクロソフト) は、お客様による申し立て手数料を速やかに払い戻し、AAA および仲裁人の手数料および費用を支払います。お客様が、仲裁人が指名される前に当社から提示された書面による最終和解案を拒否し、お客様による紛争に対して仲裁人の決定 (以下「裁定」といいます) まで行われ、仲裁人が当該最終和解案を超える賠償をお客様に認めた場合、製造業者もしくはインストール業者 (またはお客様とマイクロソフトの間の紛争である場合はマイクロソフト) は、(1) 裁定と 1,000 米ドルのいずれか高いほうの金額を支払い、(2) お客様が負担する合理的な弁護士手数料がある場合は、その金額を支払い、ならびに (3) お客様の弁護士が仲裁においてお客様の請求について調査、準備、および追求するために発生した合理的な費用 (鑑定人の手数料および費用を含む) を払い戻すものとします。金額についてお客様および当社が合意していない場合は、仲裁人が決定するものとします。
(ii)	75,000 米ドルを超える紛争。申し立て手数料、ならびに AAA および仲裁人の手数料および費用の支払いには、AAA 規則が適用されます。
(iii)	任意の金額の紛争。お客様が仲裁を開始した場合、当社は、かかる仲裁に根拠がない、またはかかる仲裁が不適切な目的で申し立てられたと仲裁人が判断した場合を除き、当社が負担する AAA もしくは仲裁人の手数料および費用、または払い戻したお客様の申し立て手数料支払いを要求しないものとします。当社が仲裁を開始した場合、当社は、申し立て、AAA、および仲裁人の手数料および費用を支払います。当社は、いかなる仲裁においても、当社が負担する弁護士の手数料または費用をお客様に要求しないものとします。手数料および費用は、係争金額を算定する際に、考慮に入れないものとします。
f.	1 年以内に申し立てること。お客様および当社は、いかなる請求または紛争 (知的財産権に関する紛争を除きます。第 10 条 a 項をご参照ください) も、申し立てることが可能になった最初の日から 1 年以内に少額裁判所に申し立てるか、または仲裁を申し立てなければなりません。1 年以内に申し立てなかった場合、かかる請求または紛争は永久に排除されます。
g.	可分性。集団訴訟の権利放棄が紛争全体または紛争の一部に対して違法または執行不能と判断された場合、その部分は仲裁ではなく裁判所で手続きが進められ、残りの部分は仲裁で手続きが進められるものとします。第 10 条に規定するその他の条項で、違法または執行不能と判断されたものがある場合、その条項は第 10 条の残りの条項とは切り離されますが、残りの条項は、引き続き適用されるものとします。
h.	AAA 規則との不一致。本ライセンス条項と AAA の商事仲裁規則または消費者仲裁規則との不一致がある場合には、本ライセンス条項が適用されます。
i.	当事者または第三者受益者としてのマイクロソフト。マイクロソフトがデバイス製造業者であるか、お客様が本ソフトウェアを小売業者から取得された場合、マイクロソフトが本ライセンス条項の当事者になります。それ以外の場合、マイクロソフトは、本ライセンス条項の当事者ではありませんが、お客様と製造業者またはインストール業者との間において裁判外の交渉および仲裁を通して紛争を解決するという契約における第三者受益者です。
11.	準拠法。契約違反に対する請求、地域の消費者保護法、不正競争防止法、および黙示の保証に関する法令に基づく請求、不当利得返還請求、ならびに不法行為に基づく請求を含む、本ソフトウェア、その対価、または本ライセンス条項に関するすべての請求および紛争には、抵触法にかかわらず、お客様の住所 (または会社の場合は主たる業務地) の地域または国の法令が適用されます。ただし、仲裁に関するすべての規定は FAA に準拠するものとします。
12.	消費者の権利、地域による差異。本ライセンス条項は、一定の法的な権利を規定します。お客様は、地域や国によっては、本ライセンス条項の定めにかかわらず、消費者としての権利など、本ライセンス条項と異なる権利を有する場合があります。また、お客様は本ソフトウェアの取得取引の相手方に対して権利を取得できる場合もあります。本ライセンス条項は、お客様の地域または国の法令が権利の変更を許容しない場合、かかる本ライセンス条項以外の権利を変更しないものとします。たとえば、お客様が以下のいずれかの地域で本ソフトウェアを取得された場合、または当該国の強行法が適用される場合、以下の規定がお客様に適用されます。
a.	オーストラリア。「品質保証規定」に関する記述は、マイクロソフト、または製造業者もしくはインストール業者により提供される明示の保証に関する記述を意味します。当該品質保証規定は、オーストラリア消費者法に基づく法定保証に従ったお客様の権利および救済を含め、法律に基づきお客様に付与されている場合があるその他の権利および救済に加えて提供されます。
本項では、「商品」とは、マイクロソフト、または製造業者もしくはインストール業者が明示の保証を提供する本ソフトウェアを意味します。マイクロソフトの商品には、オーストラリア消費者法に基づき除外することのできない保証が付随するものとします。お客様は、重大な欠陥に対する交換または返金、およびその他の合理的に予測可能なあらゆる損失または損害に対する補償を受ける権利を有します。また、お客様は、かかる商品が合格品質に至っておらず当該欠陥が重大な欠陥とはみなされない場合に、かかる商品の修理または交換を受ける権利を有します。
b.	カナダ。お客様は、インターネット アクセスを無効にすることで、お客様のデバイスで更新プログラムを受け取ることを停止できます。お客様がインターネットに再接続したときに、本ソフトウェアは更新プログラムの確認およびインストールを再開します。
c.	欧州連合。以下の第 13 条 d. (i) 項に規定されているアカデミック パックの使用の制限は、本サイト (aka.ms/academicuse) に記載されている地域では適用されません。
d.	ドイツおよびオーストリア。
(i)	保証。適切にライセンスを取得したソフトウェアは、実質的に、本ソフトウェアに付属しているマイクロソフト資料に説明されているとおり動作します。ただし、製造業者またはインストール業者、およびマイクロソフトは、ライセンスを取得したソフトウェアに関して契約上の保証は一切いたしません。
(ii)	責任の制限。製造業者もしくはインストール業者、またはマイクロソフトは、故意による行動、重過失があった場合、および製造物責任法に基づく請求が申し立てられた場合、ならびに人の死亡もしくは傷害、または物理的傷害が発生した場合、制定法に従って責任を負います。
前文に従って、製造業者もしくはインストール業者、またはマイクロソフトが重大な契約上の義務、すなわち、本ライセンス条項の正当な履行を支援する義務の遂行、本契約の目的を危うくする義務の不履行、および当事者が常に信頼できる義務の遵守 (「基本義務」といわれます) に違反した場合、製造業者もしくはインストール業者、またはマイクロソフトは軽過失に限り責任を負います。その他の軽過失については、製造業者もしくはインストール業者、またはマイクロソフトは責任を負いません。
e.	その他の地域。地域による差異の最新の一覧については、(aka.ms/variations) をご参照ください。
13.	追加の注意事項。
a.	ネットワーク、データ、およびインターネットの使用。本ソフトウェアおよび本ソフトウェアを介してアクセスするサービスの一部の機能では、お客様のデバイスからインターネットにアクセスする必要がある場合があります。お客様によるアクセスおよび使用 (料金を含みます) には、ご利用の移動体通信またはインターネット プロバイダーとの契約の条項が適用される場合があります。本ソフトウェアの一定の機能を使用すると、より効率的にインターネットにアクセスできますが、本ソフトウェアによる使用料率の計算結果はご利用のサービス プロバイダーによる算定結果と異なる場合があります。お客様は、(i) お客様自身のプランおよび契約の条項を理解して遵守すること、および (ii) パブリック ネットワークやオープン ネットワークなどのネットワークを使用またはネットワークにアクセスすることによって生じる問題、に常に責任を負うものとします。お客様は、権限がある場合に限り、本ソフトウェアを使用してネットワークに接続したり、当該ネットワークに関するアクセス情報を共有したりすることができます。
b.	H.264/AVC および MPEG-4 ビジュアル規格と VC-1 ビデオ規格。本ソフトウェアには、H.264/MPEG-4 AVC および VC-1 ビデオ デコーディング テクノロジが含まれていることがあります。このテクノロジについては、MPEG LA, L.L.C. により以下の注意書きを表示することが義務付けられています。
本製品は、消費者による個人使用および非商業的使用を前提とし、「AVC PATENT PORTFOLIO LICENSE」、「VC-1 PATENT PORTFOLIO LICENSE」、「MPEG-4 PART 2 VISUAL PATENT PORTFOLIO LICENSE」に基づいて次の用途に限ってライセンスされています。(i) 上記の規格 (以下「ビデオ規格」といいます) に従ってビデオをエンコードすること、または (ii) 個人的かつ非商業的活動に従事する消費者がエンコードした AVC、VC-1、および MPEG-4 PART 2 ビデオをデコードする、もしくは、かかるビデオを提供するライセンスを有するビデオ プロバイダーから取得したビデオをデコードすること。その他の用途については、明示か黙示かを問わず、いかなるライセンスも許諾されません。詳細情報については、MPEG LA, L.L.C. から入手できます。(AKA.MS/MPEGLA) をご参照ください。
c.	マルウェア対策。マイクロソフトは、お客様のデバイスをマルウェアから保護することに注意を払っています。本ソフトウェアでは、他の対策がインストールされていないか、有効期限が切れている場合、マルウェア対策が有効になります。有効にするには、他のマルウェア対策ソフトウェアを無効にするか、場合によっては削除する必要があります。
d.	権利限定バージョン。お客様が取得された本ソフトウェアのバージョンについて、特定または限定用途と明記されているか、その他かかる用途が意図されている場合、お客様は特定されている用途に限り、本ソフトウェアを使用することができます。お客様は、かかるバージョンの本ソフトウェアを、商用、非営利、または収益が発生する活動で使用することはできません。
(i)	アカデミック パック。アカデミック パックを使用する場合、お客様は、購入時点で教育機関の学生、教職員、またはスタッフでなければなりません。
(ii)	評価版。評価 (またはテストもしくはデモンストレーション) 版を使用する場合、お客様は、本ソフトウェアを販売すること、実際の運用環境で使用すること、または評価期間の経過後に使用することはできません。本ライセンス条項にこれと異なる規定がある場合でも、評価版ソフトウェアは「現状有姿」で提供されます。
(iii)	NFR。お客様は、「NFR」または「Not for Resale」と明記されているソフトウェアを販売することはできません。
14.	完全合意。本ライセンス条項 (および製造業者もしくはインストール業者、またはマイクロソフトが提供し、お客様が使用する、任意の追加ソフトウェア、更新プログラム、およびサービスに付属する、印刷されたライセンス条項またはその他の条項) ならびに本ライセンス条項に記載されている Web リンクに掲載されている条項は、本ソフトウェアならびに当該追加ソフトウェア、更新プログラム、およびサービスに関する完全なる合意です (ただし、製造業者もしくはインストール業者、またはマイクロソフトが、当該追加ソフトウェア、更新プログラム、またはサービスについてその他の条項を提供している場合は、この限りではありません)。本ライセンス条項は、本ソフトウェアの実行後、(aka.ms/useterms) にアクセスするか、本ソフトウェアから [設定]、[システム]、[バージョン情報] の順に選択することで確認できます。また、本ライセンス条項に記載されているリンク先に掲載されている条項は、ブラウザーのアドレス バーにその URL を入力することでも確認できます。お客様は、かかる条項を確認するものとします。お客様は、本ソフトウェアまたはサービスを使用する前に、リンク先の条項を含む本ライセンス条項をお読みになるものとします。お客様は、本ソフトウェアおよびサービスを使用することによって本ライセンス条項およびリンク先の条項を承認することとなることを理解するものとします。また、本ライセンス条項には情報が掲載されているリンクも記載されています。注意事項および拘束力のある条項が記載されたリンクは、以下のとおりです。
·	Windows 10 のプライバシーに関する声明 (aka.ms/privacy)
·	Microsoft サービス規約 (aka.ms/msa)
·	Adobe Flash Player ライセンス条項 (aka.ms/adobeflash)


***********************************************************************
品質保証規定
デバイス製造業者またはインストール業者は、適切にライセンスを取得したソフトウェアが実質的に、本ソフトウェアに付属しているマイクロソフト資料に説明されているとおり動作することを保証します。本品質保証規定の有効期間である 90 日間においてお客様がマイクロソフトから直接取得された更新プログラムまたは追加ソフトウェアについては、マイクロソフトが本品質保証規定を履行します。本品質保証規定では、お客様が原因となって生じた問題、お客様が指示に従わなかったことで生じた問題、または製造業者、インストール業者もしくはマイクロソフトの合理的な支配の及ばない事柄に起因して発生した問題は対象としていません。品質保証規定は、最初のユーザーが本ソフトウェアを取得した日から発効し、その後 90 日間有効です。90 日間の有効期間内にお客様が製造業者、インストール業者またはマイクロソフトから受け取ることのあるすべての追加ソフトウェア、更新プログラム、または交換ソフトウェアも保証の対象となりますが、その場合は、当該 90 日間の有効期間の残りの日数か、または 30 日間のいずれか長いほうの期間、保証されます。本ソフトウェアを譲渡しても、その品質保証規定の期間が延長されることはありません。
製造業者、インストール業者およびマイクロソフトは、その他の明示の保証、条件、瑕疵担保、またはその他本ソフトウェアの品質について一切責任を負いません。製造業者、インストール業者およびマイクロソフトは、商品性、特定目的に対する適合性、または権利侵害の不存在に関する黙示の保証および条件を含め、いかなる黙示の保証または条件についても一切責任を負いません。地域の法律により、黙示の保証の制限をマイクロソフトが行うことが認められていない場合、黙示の保証は、上記の品質保証規定期間中に限り、法律上許容される限り限定された内容において、お客様に与えられるものとします。お客様の地域の法律によって、契約上の制限にかかわらず、より長い有効期間が品質保証規定に求められる場合、当該より長い期間が適用されます。ただし、お客様が請求しうる内容は、本ライセンス条項で許可されている内容に限定されます。
製造業者、インストール業者またはマイクロソフトが品質保証規定に違反した場合、当社は、自らの裁量において、(i) 無償で本ソフトウェアを修理もしくは交換するか、または (ii) 本ソフトウェア (もしくは当社の裁量により、本ソフトウェアがプレインストールされたデバイス) の返品を受け入れて購入金額を払い戻します。製造業者もしくはインストール業者 (または、お客様が直接マイクロソフトから取得した場合は、マイクロソフト) は、追加ソフトウェア、更新プログラム、および本ソフトウェアを修理もしくは交換するか、またはお客様が支払われた金額を払い戻すこともできます。以上が、品質保証規定違反に対する、お客様への唯一の権利となります。本品質保証規定は、お客様の法的な権利を定めたものです。また、お客様は地域によって、その他の権利を有する場合があります。
製造業者、インストール業者またはマイクロソフトが提供することのある修理、交換、または払い戻しを除き、本品質保証規定、本ライセンス条項の他のすべての部分、またはその他の法理に基づいても、お客様はいかなる損害 (逸失利益、直接損害、結果的損害、特別損害、間接損害、付随的損害を含みます) の賠償またはその他の請求を行うことはできません。本ライセンス条項に規定する損害の免責および救済手段の制限は、修理、交換、または払い戻しによってお客様の損失が完全に補償されない場合、製造業者、インストール業者またはマイクロソフトがこのような損害の可能性を認識していたか、もしくは認識し得た場合、または本ライセンス条項に規定する救済手段がその実質的目的を達成できない場合にも適用されます。一部の地域または国では付随的損害、結果的損害、または他の損害の免責または責任の制限が認められないため、かかる責任の制限または免責がお客様に適用されない場合があります。お客様の地域の法律において、かかる契約上の責任の制限または免責にもかかわらず、製造業者、インストール業者またはマイクロソフトに損害の賠償を請求することが認められる場合、お客様が請求できる金額は、お客様が本ソフトウェアに対して支払った金額 (またはお客様が本ソフトウェアを無償で取得した場合は 50 米ドル) を上限とします。
保証に関するお問い合わせ
サービスまたは返金を受ける場合、お客様は、お客様の購入証明書を提供し、製造業者またはインストール業者の返品方針に従わなければなりません。この方針により、お客様は、本ソフトウェアと共に、本ソフトウェアがインストールされているデバイス全体を返品することが求められる場合があります。プロダクト キーを含む Certificate of Authenticity ラベルは、お客様のデバイスと共に提供された場合、貼付されたままでなければなりません。
本ソフトウェアの保証サービスについては、製造業者またはインストール業者に、お客様のデバイスと共に提供されている住所または通話料無料の電話番号を利用してお問い合わせください。マイクロソフトがデバイス製造業者であるか、お客様が本ソフトウェアを小売業者から取得された場合、下記のいずれかの連絡先までご連絡ください。
1.	米国およびカナダ。米国またはカナダで入手された本ソフトウェアに関する保証サービスまたは返金に関して不明な点がございましたら、(800) MICROSOFT まで電話でご連絡いただくか、Microsoft Customer Service and Support (One Microsoft Way, Redmond, WA 98052-6399) まで郵便でご連絡いただくか、または (aka.ms/nareturns) をご覧ください。
2.	ヨーロッパ、中東、およびアフリカ。本ソフトウェアをヨーロッパ、中東、またはアフリカで入手された場合、Microsoft Ireland Operations Limited (Customer Care Centre, Atrium Building Block B, Carmanhall Road, Sandyford Industrial Estate, Dublin 18, Ireland) または最寄りのマイクロソフト関連会社 (aka.ms/msoffices) までご連絡ください。
3.	オーストラリア。本ソフトウェアをオーストラリアで入手された場合、13 20 58 まで電話でご連絡いただくか、Microsoft Pty Ltd (1 Epping Road, North Ryde NSW 2113 Australia) まで郵便でご連絡いただき、請求を行ってください。
4.	その他の国。上記の国以外で本ソフトウェアを入手された場合は、最寄りのマイクロソフトの関連会社までご連絡ください。連絡先については、(aka.ms/msoffices) をご参照ください。日本については、www.microsoft.com/japan/ をご参照ください。

Raspberry Piで温度を測ろう

投稿日:

 以前、Arduinoのアナログ入力にサーミスタをつなぎ、温度計にして遊んだ最近はLCDディスプレイに温度を表示してみたり、なかなか面白い。

 一方、Raspberry PiはWebによくなじむ。ApacheもPHPも走る。

IMG_3317 それで、先週宮城大学小島研究室のサイトで公開しておられるADCアクセスのためのソースコードを拝借して遊んだが、これを使ってWeb温度計にしてみた。

 まず、ブレッドボードにAD変換ICのMCP3208と、サーミスタ、分圧用の抵抗1kΩを置き、適切に配線する。これには、以前Arduinoで遊ぶために買った「Seeedstudio Arduino Sidekick Basic Kit」に入っていたMF11-503Kというサーミスタをそのまま使う。

 それから、C++でこんなプログラムを書く。先週も書いたが、宮城大学小島研究室のサイトで公開しておられるコードは、Raspberry Pi 1では何の支障もなく動くが、Raspberry Pi 2 Model Bではそのままでは動かない。一部の型キャストなどを変更する必要がある。それについては先週のエントリで記してある。

//
//    tempMesure.cpp
//      佐藤俊夫
//      Sun Sep  6 13:57:53 JST 2015
//      サーミスタMF11-503Kと1kΩ抵抗を直列につなぎ、3.3Vを印加して、
//      その間から分圧をとって温度を測る。
//      宮城大学小島研究室でウェブ公開しておられるソースコードを拝借した。
//      コンパイル
//        cc -lm tempMesure.cpp raspSPI.o raspADC.o -o tempMesure
//
#include <stdio.h>
#include <math.h>
#include "raspADC.h"

#define ADC_CHIP  ADC_3208
float tempMesure(int srcVal);

int main() {
  ADC adc;

  adc.init("/dev/spidev0.1", ADC_CHIP);
  printf("%2.2f\n", tempMesure(adc.get(0)));
}

float tempMesure(int srcVal){
  const float B = 4350.0, Ta = 25.0, Rt0 = 50000.0;  //  MF11-503Kスペックシート記載
  const float K = 273.15;  //  熱力学温度の定数
  const float v0 = 3.3, r0 = 1000.0;  //  Arduino +5Vと電流調整抵抗1kΩ
  const int resolution = 4096;  //  アナログ入力の分解能
  float vt = 0.0, rt = 0.0;

  vt = srcVal * (v0 / (resolution - 1));
  rt = (v0 * r0 - vt * r0) / vt;
  return(1.0 / (log(rt / Rt0) / B + 1.0 / (Ta + K)) - K);
}

 これは単に、サーミスタで計った現在の温度を標準出力に書くだけだ。

 これを「popen();」で開けば、PHPで読める。簡単である。

<html>
 <head>
  <meta name="Editor" content="vim">
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <link rel="icon" href="favicon.ico" type="image/x-icon" />
  <link rel="Shortcut Icon" type="image/x-icon" href="favicon.ico" />
  <title>PHPで温度計</title>
  <meta http-equiv="Keyword" content="佐藤俊夫, 佐藤, 俊夫, SATOTOSHIO, SatoToshio, sato, toshio, Raspberry Pi, Raspberry Pi 2 Model B">
 </head>
 <body bgcolor="#888888">
<body>
  <center>
  <h1><img src="raspberry_pi.png" width="50px" align="middle"/>Raspberry Pi + PHPで温度計</h1>
  <hr>
  </center>
<?
ini_set( 'display_errors', 1 );
$process = popen("sudo /home/toshio/SPI_ADC/tempMesure", "r");
$temp = fgets($process);
?>
<center>
<table border=1 width="120px">
<tr> <th>0</th><th>10</th> <th>20</th> <th>30</th> <th>40</th> <th>50</th> <th>60</th></tr>
<tr><td colspan = 7>
<table>
<tr>
<td bgcolor="red" width="<?print $temp * 2?>px"><?print $temp?>℃</td&t;</tr></table>
</tr>
</table>
</td></tr></tr></table>
</center>
</body>
</html>

raspberry_tempMesure
 テーブルの幅を温度計のアルコール柱に見立てて、赤い帯で表すようにしてみた。


 Arduinoでも同じようなことはできるが、Arduinoで難しいのは、こういうふうに、無駄に画像を配置したり、少し分量の多いHTMLを書いたりすることだ。だが、こんなことはRaspberry Piには造作もなくできてしまう。

 反面、Arduinoはアナログ入力が直接可能だが、Raspberry Piで同じことをしようとすると、アナログ入力にAD変換ICを準備し、これとの通信にもいろいろと研究の上で取り組む必要がある。簡単で刺激的な目的のために少しプロトタイピングをしてみようと考えている多くのクリエイターがなしうるところではない。

 入門書籍「Raspberry Piをはじめよう」にもそうしたことが少し書かれてある。

そうか、PHPでもモノにつながるな

投稿日:

raspi_index Raspberry Piは要するにLinuxマシンなので、ウェブサーバも選り取り見取りだ。単にウェブインターフェイスを備えたモノのプロトをするならArduinoのほうが手っ取り早いが、いかんせん、リッチなウェブ・コンテンツをArduino+ETHERNET SHIELD 2でサービスするのは難しく、不可能ではないにもせよ、ウェブ・コンテンツに写真を置くなどというのはほとんど無理であった。

 Raspberry Piはコンピュータ・パワーが大きいから、大きなウェブ・コンテンツも本体内に飲み込んでしまえる。

 そこで、である。Raspberry Piで遊ぶのに、なにも世間の教科書通りにPythonやRubyの作例を打ち込むだけが能ではない。CだってC++だって、PerlだってPHPだって動くはずである。SMTPもPOPもNTPも、なんだって動く。多分MySQLだのPostgreSQLだのも動くだろう。

 Apacheをインストールして動かしてみよう。それから、PHPでGPIOを突っついてみよう。これは、PHPでハードウェアを動かすことにつながる。無駄に贅沢なWebインターフェイスでLチカ、というのも面白い。

Apacheのインストールに先立ち、今動いているサービスを確かめよう

 まず、今起動しているモノを確認してみよう。RedHat系のLinux、Fedoraなどはこういう時に「chkconfig –list」などとするが、Raspberry Piに入っているのは「Raspbian」だ。RaspbianはDebian系のディストリビューションなので、chkconfigはない。

 私はUNIX育ちのオッサンで、SVR4.2の管理人を長年やっきた。Linuxに関してはフリー時代のRedHat(4~9ぐらいまで)、それ以降はずっとFedora Coreを使ってきたので、Debianは良く知らないのである。ま、これも機会だから、ちょっと体験してみようではないの。

 ネット情報によると「insserv」「update-rc.d」「sysv-rc-conf」「rcconf」「upstart」などがあるという。

# insserv -s
K:01:0 1 6:triggerhappy
K:07:0 6:umountfs
K:04:0 6:umountnfs.sh
K:02:0 6:sendsigs
K:01:0 6:plymouth
K:03:0 1 6:rsyslog
K:06:0 6 S:hwclock.sh
K:01:0 1 6:alsa-utils
K:06:0 6:networking
K:05:0 1 2 3 4 5 6 S:rpcbind
K:05:0 1 2 3 4 5 6 S:nfs-common
K:01:0 6:urandom
K:01:0 1 6:avahi-daemon
K:01:0 1 6:dhcpcd
K:01:0 1 6:cgroup-bin
K:08:0 6:umountroot
K:09:0:halt
K:09:6:reboot
K:01:0 1 6:fake-hwclock
K:01:0 1 2 6:lightdm
K:01:0 1 6:ifplugd
S:02:S:udev
S:03:S:keyboard-setup
S:15:S:console-setup
S:01:2 3 4 5:triggerhappy
S:08:S:mountall.sh
S:09:S:mountall-bootclean.sh
S:12:S:mountnfs.sh
S:13:S:mountnfs-bootclean.sh
S:04:2 3 4 5:plymouth
S:01:2 3 4 5:rsyslog
S:16:S:alsa-utils
S:11:S:networking
S:10:S:urandom
S:04:S:mountdevsubfs.sh
S:05:S:checkroot.sh
S:03:2 3 4 5:avahi-daemon
S:02:2 3 4 5:dbus
S:01:2 3 4 5:dhcpcd
S:01:2 3 4 5:cgroup-bin
S:01:S:mountkernfs.sh
S:01:S:fake-hwclock
S:03:3 4 5:lightdm
S:16:S:x11-common
S:14:S:kbd
S:01:2 3 4 5:ifplugd
S:02:1:single
S:01:1:killprocs
S:01:1 2 3 4 5:bootlogs
S:01:S:hostname.sh
S:01:1 2 3 4 5:motd
S:02:2 3 4 5:dphys-swapfile
S:04:2 3 4 5:rc.local
S:04:2 3 4 5:rmnologin
S:02:2 3 4 5:cron
S:02:2 3 4 5:rsync
S:02:2 3 4 5:ssh
S:02:2 3 4 5:ntp
S:01:2 3 4 5:sudo
S:16:S:raspi-config
S:10:S:udev-mtab
S:06:S:checkroot-bootclean.sh
S:16:S:bootmisc.sh
S:06:S:kmod
S:16:S:plymouth-log
S:07:S:checkfs.sh
S:06:S:mtab.sh
S:10:S:procps

 ほほー、なるほど、コレは多分、左から現状(StartかKillか)、起動順、起動すべきRun-Levelのリスト、サービス名、だろうなあ。はて、S、Kじゃないほうの、Run-Levelの「S」は、なんだろ、と調べると、「起動順で一番はじめ、かつ、どのRun-Levelでも共通で起動」ということのようである。

 で、

# insserv -s | egrep '(pache)|(ttp)'
#

 なんてことをやっても、全然何も出ないから、デフォルトのRaspbianではhttpらしきものやApacheらしきものは何も動いていない。

Apacheをインストール

 それでは、というわけで、

# apt-get -s install apache2
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1 libaprutil1
  libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert
提案パッケージ:
  apache2-doc apache2-suexec apache2-suexec-custom openssl-blacklist
以下のパッケージが新たにインストールされます:
  apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1
  libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert
アップグレード: 0 個、新規インストール: 10 個、削除: 0 個、保留: 0 個。
Inst libapr1 (1.4.6-3+deb7u1 Raspbian:7.0/oldstable [armhf])
Inst libaprutil1 (1.4.1-3 Raspbian:7.0/oldstable [armhf])
Inst libaprutil1-dbd-sqlite3 (1.4.1-3 Raspbian:7.0/oldstable [armhf])
Inst libaprutil1-ldap (1.4.1-3 Raspbian:7.0/oldstable [armhf])
Inst apache2.2-bin (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Inst apache2-utils (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Inst apache2.2-common (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Inst apache2-mpm-worker (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Inst apache2 (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Inst ssl-cert (1.0.32 Raspbian:7.0/oldstable [all])
Conf libapr1 (1.4.6-3+deb7u1 Raspbian:7.0/oldstable [armhf])
Conf libaprutil1 (1.4.1-3 Raspbian:7.0/oldstable [armhf])
Conf libaprutil1-dbd-sqlite3 (1.4.1-3 Raspbian:7.0/oldstable [armhf])
Conf libaprutil1-ldap (1.4.1-3 Raspbian:7.0/oldstable [armhf])
Conf apache2.2-bin (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Conf apache2-utils (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Conf apache2.2-common (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Conf apache2-mpm-worker (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Conf apache2 (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Conf ssl-cert (1.0.32 Raspbian:7.0/oldstable [all])
#

 特に問題なさそうだな、というわけで……

# apt-get install apache2
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1 libaprutil1
  libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert
提案パッケージ:
  apache2-doc apache2-suexec apache2-suexec-custom openssl-blacklist
以下のパッケージが新たにインストールされます:
  apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common libapr1
  libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap ssl-cert
アップグレード: 0 個、新規インストール: 10 個、削除: 0 個、保留: 0 個。
1,356 kB のアーカイブを取得する必要があります。
この操作後に追加で 4,585 kB のディスク容量が消費されます。
続行しますか [Y/n]? y
取得:1 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libapr1 armhf 1.4.6-3+deb7u1 [90.9 kB]
取得:2 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libaprutil1 armhf 1.4.1-3 [77.1 kB]
取得:3 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libaprutil1-dbd-sqlite3 armhf 1.4.1-3 [17.2 kB]
取得:4 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libaprutil1-ldap armhf 1.4.1-3 [16.0 kB]
取得:5 http://mirrordirector.raspbian.org/raspbian/ wheezy/main apache2.2-bin armhf 2.2.22-13+deb7u6 [676 kB]
取得:6 http://mirrordirector.raspbian.org/raspbian/ wheezy/main apache2-utils armhf 2.2.22-13+deb7u6 [163 kB]
取得:7 http://mirrordirector.raspbian.org/raspbian/ wheezy/main apache2.2-common armhf 2.2.22-13+deb7u6 [292 kB]
取得:8 http://mirrordirector.raspbian.org/raspbian/ wheezy/main apache2-mpm-worker armhf 2.2.22-13+deb7u6 [2,238 B]
取得:9 http://mirrordirector.raspbian.org/raspbian/ wheezy/main apache2 armhf 2.2.22-13+deb7u6 [1,440 B]
取得:10 http://mirrordirector.raspbian.org/raspbian/ wheezy/main ssl-cert all 1.0.32 [19.5 kB]
1,356 kB を 4秒 で取得しました (281 kB/s)
パッケージを事前設定しています ...
以前に未選択のパッケージ libapr1 を選択しています。
(データベースを読み込んでいます ... 現在 78616 個のファイルとディレクトリがインストールされています。)
(.../libapr1_1.4.6-3+deb7u1_armhf.deb から) libapr1 を展開しています...
以前に未選択のパッケージ libaprutil1 を選択しています。
(.../libaprutil1_1.4.1-3_armhf.deb から) libaprutil1 を展開しています...
以前に未選択のパッケージ libaprutil1-dbd-sqlite3 を選択しています。
(.../libaprutil1-dbd-sqlite3_1.4.1-3_armhf.deb から) libaprutil1-dbd-sqlite3 を展開しています...
以前に未選択のパッケージ libaprutil1-ldap を選択しています。
(.../libaprutil1-ldap_1.4.1-3_armhf.deb から) libaprutil1-ldap を展開しています...
以前に未選択のパッケージ apache2.2-bin を選択しています。
(.../apache2.2-bin_2.2.22-13+deb7u6_armhf.deb から) apache2.2-bin を展開しています...
以前に未選択のパッケージ apache2-utils を選択しています。
(.../apache2-utils_2.2.22-13+deb7u6_armhf.deb から) apache2-utils を展開しています...
以前に未選択のパッケージ apache2.2-common を選択しています。
(.../apache2.2-common_2.2.22-13+deb7u6_armhf.deb から) apache2.2-common を展開しています...
以前に未選択のパッケージ apache2-mpm-worker を選択しています。
(.../apache2-mpm-worker_2.2.22-13+deb7u6_armhf.deb から) apache2-mpm-worker を展開していま す...
以前に未選択のパッケージ apache2 を選択しています。
(.../apache2_2.2.22-13+deb7u6_armhf.deb から) apache2 を展開しています...
以前に未選択のパッケージ ssl-cert を選択しています。
(.../ssl-cert_1.0.32_all.deb から) ssl-cert を展開しています...
man-db のトリガを処理しています ...
libapr1 (1.4.6-3+deb7u1) を設定しています ...
libaprutil1 (1.4.1-3) を設定しています ...
libaprutil1-dbd-sqlite3 (1.4.1-3) を設定しています ...
libaprutil1-ldap (1.4.1-3) を設定しています ...
apache2.2-bin (2.2.22-13+deb7u6) を設定しています ...
apache2-utils (2.2.22-13+deb7u6) を設定しています ...
apache2.2-common (2.2.22-13+deb7u6) を設定しています ...
Enabling site default.
Enabling module alias.
Enabling module autoindex.
Enabling module dir.
Enabling module env.
Enabling module mime.
Enabling module negotiation.
Enabling module setenvif.
Enabling module status.
Enabling module auth_basic.
Enabling module deflate.
Enabling module authz_default.
Enabling module authz_user.
Enabling module authz_groupfile.
Enabling module authn_file.
Enabling module authz_host.
Enabling module reqtimeout.
apache2-mpm-worker (2.2.22-13+deb7u6) を設定しています ...
[....] Starting web server: apache2apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
. ok
apache2 (2.2.22-13+deb7u6) を設定しています ...
ssl-cert (1.0.32) を設定しています ...
#

 なんてことなく終わる。

Apacheの起動状況を確かめる

 次に、

# insserv -s | egrep '(pache)|(ttp)'
K:01:0 1 6:apache2
S:02:2 3 4 5:apache2
#

……ぬぅ、StartなのかKillなのか、どっちやねん、というわけで、ブラウザにアドレスを入れてみると、

raspi-apache2start

……と、普通にApacheは動いている。KとS両方出るのは、起動順が01、02となっていることから、Run-Level 0、1、6ではどうあろうと強制終了し、改めて2、3、4、5では起動、ということであろうか。

 えーっと、自動起動のほうはこれでいいから、サービスの起動停止のテストは……、と。

# /etc/init.d/apache2 stop
[....] Stopping web server: apache2apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
[ ok waiting ..
root@satoraspi:~# /etc/init.d/apache2 start
[....] Starting web server: apache2apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
. ok
#

 ふむ、だいだい動いとる。

ドキュメントルートのindex.htmlを作る

 とりあえず、indexだけ、かっこよくしておこう。えーっと、ドキュメントルートはどこかいな、と。

# ls -Fla /etc/ | egrep '(http)|(apache)'
drwxr-xr-x   7 root root    4096  8月 30 09:01 apache2/
root@satoraspi:~# ls /etc/apache2
apache2.conf  envvars  mods-available  ports.conf       sites-enabled
conf.d        magic    mods-enabled    sites-available
# cd /etc/apache2
# grep 'DocumentRoot' */*
sites-available/default:        DocumentRoot /var/www
sites-available/default-ssl:    DocumentRoot /var/www
sites-enabled/000-default:      DocumentRoot /var/www

 ……と、いうわけで普通に「/var/www」の下じゃのう。普通のユーザに戻って、

toshio@satoraspi:~$ cd /var/www
toshio@satoraspi:/var/www$ ls -Fla
合計 12
drwxr-xr-x  2 root root 4096  8月 30 09:01 ./
drwxr-xr-x 12 root root 4096  8月 30 09:01 ../
-rw-r--r--  1 root root  177  8月 30 09:01 index.html
toshio@satoraspi:/var/www$ cat index.html
<html><body><h1>It works!</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
</body></html>toshio@satoraspi:/var/www$

 はあ、さっきブラウザに出てたヤツでんな、と。

 一応残しておいて……

toshio@satoraspi:/var/www$ sudo cp index.html .index.html.ORG
[sudo] password for toshio:
toshio@satoraspi:/var/www$ sudo chown toshio:pi index.html
toshio@satoraspi:/var/www$ ls -Fla
合計 16
drwxr-xr-x  2 root   root 4096  8月 30 09:37 ./
drwxr-xr-x 12 root   root 4096  8月 30 09:01 ../
-rw-r--r--  1 root   root  177  8月 30 09:37 .index.html.ORG
-rw-r--r--  1 toshio pi    177  8月 30 09:01 index.html
toshio@satoraspi:/var/www$cd ..
toshio@satoraspi:/var$sudo chown toshio:pi www
toshio@satoraspi:/var$cd www
toshio@satoraspi:/var/www$vi index.html

 んで、ばーっ、って、書くですよ。

<html>
 <head>
  <meta name="Editor" content="vim">
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <link rel="icon" href="favicon.ico" type="image/x-icon" />
  <link rel="Shortcut Icon" type="image/x-icon" href="favicon.ico" />
  <title>おっさん用Raspberry Pi 2 Model B</title>
  <meta http-equiv="Keyword" content="佐藤俊夫, 佐藤, 俊夫, SATOTOSHIO, SatoToshio, sato, toshio, Raspberry Pi, Raspberry Pi 2 Model B">
 </head>
 <body bgcolor="#888888">
  <basefont size=4">
  <center>
  <table>
  <tr>
  <td>
    <h1>おっさん用Raspberry Pi 2 Model B</h1>
    <hr>
    <center><img src="raspberry_pi.png"></center>
  </td>
  </tr>
  <tr>
  <td>
    とりあえずまだ何もない。
  </td>
  </tr>
 </table>
 </center>
 </body>
</html>

 んで、画像なんかをSCPでコピーして、まずはこんなindex.htmlですな。

raspi_index

 それにしても、こんな、5千円かそこらのシングルボードでapache2のウェブサービスができるなんて、隔世の感があるな。

同じようにして、PHPをインストール

 さておき、続いてPHPを入れよう。

toshio@satoraspi:/var/www$ cd
toshio@satoraspi:~$ su -
パスワード:
root@satoraspi:~# apt-cache search php5
dwoo - PHP5 template engine
libapache2-mod-php5 - server-side, HTML-embedded scripting language (Apache 2 module)
libapache2-mod-php5filter - server-side, HTML-embedded scripting language (apache 2 filter module)
libexpect-php5 - expect module for PHP 5
libgv-php5 - PHP5 bindings for graphviz
libkohana2-modules-php - lightweight PHP5 MVC framework (extension modules)
libkohana2-php - lightweight PHP5 MVC framework
libkohana3.1-core-php - PHP5 framework core classes
libkohana3.1-php - PHP5 framework metapackage
libkohana3.2-core-php - PHP5 framework core classes
libkohana3.2-php - PHP5 framework metapackage
libow-php5 - Dallas 1-wire support: PHP5 bindings
libphp-jpgraph - Object oriented graph library for php5
libphp-jpgraph-examples - Object oriented graph library for php5 (examples)
libphp5-embed - HTML-embedded scripting language (Embedded SAPI library)
php-doc - Documentation for PHP5
php-imlib - PHP Imlib2 Extension
php5 - server-side, HTML-embedded scripting language (metapackage)
php5-adodb - Extension optimising the ADOdb database abstraction library
php5-cgi - server-side, HTML-embedded scripting language (CGI binary)
php5-cli - command-line interpreter for the php5 scripting language
php5-common - Common files for packages built from the php5 source
php5-curl - CURL module for php5
php5-dbg - Debug symbols for PHP5
php5-dev - Files for PHP5 module development
php5-enchant - Enchant module for php5
php5-exactimage - fast image manipulation library (PHP bindings)
php5-ffmpeg - audio and video support via ffmpeg for php5
php5-fpm - server-side, HTML-embedded scripting language (FPM-CGI binary)
php5-gd - GD module for php5
php5-gdcm - Grassroots DICOM PHP5 bindings
php5-geoip - GeoIP module for php5
php5-gmp - GMP module for php5
php5-imagick - ImageMagick module for php5
php5-imap - IMAP module for php5
php5-interbase - interbase/firebird module for php5
php5-intl - internationalisation module for php5
php5-lasso - Library for Liberty Alliance and SAML protocols - PHP 5 bindings
php5-ldap - LDAP module for php5
php5-librdf - PHP5 language bindings for the Redland RDF library
php5-mapscript - php5-cgi module for MapServer
php5-mcrypt - MCrypt module for php5
php5-memcache - memcache extension module for PHP5
php5-memcached - memcached extension module for PHP5, uses libmemcached
php5-midgard2 - Midgard2 Content Repository - PHP5 language bindings and module
php5-ming - Ming module for php5
php5-mysql - MySQL module for php5
php5-mysqlnd - MySQL module for php5 (Native Driver)
php5-odbc - ODBC module for php5
php5-pgsql - PostgreSQL module for php5
php5-ps - ps module for PHP 5
php5-pspell - pspell module for php5
php5-radius - PECL radius module for PHP 5
php5-recode - recode module for php5
php5-remctl - PECL module for Kerberos-authenticated command execution
php5-rrd - rrd module for PHP 5
php5-sasl - Cyrus SASL extension for PHP 5
php5-snmp - SNMP module for php5
php5-sqlite - SQLite module for php5
php5-svn - PHP Bindings for the Subversion Revision control system
php5-sybase - Sybase / MS SQL Server module for php5
php5-tidy - tidy module for php5
php5-tokyo-tyrant - PHP interface to Tokyo Cabinet's network interface, Tokyo Tyrant
php5-vtkgdcm - Grassroots DICOM VTK PHP bindings
php5-xcache - Fast, stable PHP opcode cacher
php5-xdebug - Xdebug Module for PHP 5
php5-xmlrpc - XML-RPC module for php5
php5-xsl - XSL module for php5
phpunit - Unit testing suite for PHP5
root@satoraspi:~#

 はあ、いっぱい出たけど、要するにPHP5があるんだよな。うん、うん。

root@satoraspi:~# apt-get -s install php5
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  apache2-mpm-prefork libapache2-mod-php5 libonig2 libqdbm14 lsof php5-cli php5-common
提案パッケージ:
  php-pear
以下のパッケージは「削除」されます:
  apache2-mpm-worker
以下のパッケージが新たにインストールされます:
  apache2-mpm-prefork libapache2-mod-php5 libonig2 libqdbm14 lsof php5 php5-cli
  php5-common
アップグレード: 0 個、新規インストール: 8 個、削除: 1 個、保留: 0 個。
Remv apache2-mpm-worker [2.2.22-13+deb7u6] [apache2:armhf ]
Inst apache2-mpm-prefork (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Conf apache2-mpm-prefork (2.2.22-13+deb7u6 Raspbian:7.0/oldstable [armhf])
Inst lsof (4.86+dfsg-1 Raspbian:7.0/oldstable [armhf])
Inst php5-common (5.4.44-0+deb7u1 Raspbian:7.0/oldstable [armhf])
Inst libonig2 (5.9.1-1 Raspbian:7.0/oldstable [armhf])
Inst libqdbm14 (1.8.78-2 Raspbian:7.0/oldstable [armhf])
Inst libapache2-mod-php5 (5.4.44-0+deb7u1 Raspbian:7.0/oldstable [armhf])
Inst php5 (5.4.44-0+deb7u1 Raspbian:7.0/oldstable [all])
Inst php5-cli (5.4.44-0+deb7u1 Raspbian:7.0/oldstable [armhf])
Conf lsof (4.86+dfsg-1 Raspbian:7.0/oldstable [armhf])
Conf php5-common (5.4.44-0+deb7u1 Raspbian:7.0/oldstable [armhf])
Conf libonig2 (5.9.1-1 Raspbian:7.0/oldstable [armhf])
Conf libqdbm14 (1.8.78-2 Raspbian:7.0/oldstable [armhf])
Conf libapache2-mod-php5 (5.4.44-0+deb7u1 Raspbian:7.0/oldstable [armhf])
Conf php5 (5.4.44-0+deb7u1 Raspbian:7.0/oldstable [all])
Conf php5-cli (5.4.44-0+deb7u1 Raspbian:7.0/oldstable [armhf])
root@satoraspi:~#

 入れても大丈夫みたいだ。

root@satoraspi:~# apt-get  install php5
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
  apache2-mpm-prefork libapache2-mod-php5 libonig2 libqdbm14 lsof php5-cli php5-common
提案パッケージ:
  php-pear
以下のパッケージは「削除」されます:
  apache2-mpm-worker
以下のパッケージが新たにインストールされます:
  apache2-mpm-prefork libapache2-mod-php5 libonig2 libqdbm14 lsof php5 php5-cli
  php5-common
アップグレード: 0 個、新規インストール: 8 個、削除: 1 個、保留: 0 個。
6,142 kB のアーカイブを取得する必要があります。
この操作後に追加で 17.3 MB のディスク容量が消費されます。
続行しますか [Y/n]? y
取得:1 http://mirrordirector.raspbian.org/raspbian/ wheezy/main apache2-mpm-prefork armhf 2.2.22-13+deb7u6 [2,342 B]
取得:2 http://mirrordirector.raspbian.org/raspbian/ wheezy/main lsof armhf 4.86+dfsg-1 [321 kB]
取得:3 http://mirrordirector.raspbian.org/raspbian/ wheezy/main php5-common armhf 5.4.44-0+deb7u1 [621 kB]
取得:4 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libonig2 armhf 5.9.1-1 [130 kB]
取得:5 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libqdbm14 armhf 1.8.78-2 [119 kB]
取得:6 http://mirrordirector.raspbian.org/raspbian/ wheezy/main libapache2-mod-php5 armhf 5.4.44-0+deb7u1 [2,479 kB]
取得:7 http://mirrordirector.raspbian.org/raspbian/ wheezy/main php5 all 5.4.44-0+deb7u1 [1,024 B]
取得:8 http://mirrordirector.raspbian.org/raspbian/ wheezy/main php5-cli armhf 5.4.44-0+deb7u1 [2,469 kB]
6,142 kB を 6秒 で取得しました (1,016 kB/s)
dpkg: apache2-mpm-worker: 依存関係に問題があります。しかし要求に従い削除しています:
 apache2 は以下に依存 (depends) します: apache2-mpm-worker (= 2.2.22-13+deb7u6) | apache2-mpm-prefork (= 2.2.22-13+deb7u6) | apache2-mpm-event (= 2.2.22-13+deb7u6) | apache2-mpm-itk (= 2.2.22-13+deb7u6) ...しかし:
  パッケージ apache2-mpm-worker は削除されようとしています。
  パッケージ apache2-mpm-prefork はまだインストールされていません。
  パッケージ apache2-mpm-event はまだインストールされていません。
  パッケージ apache2-mpm-itk はまだインストールされていません。

(データベースを読み込んでいます ... 現在 79208 個のファイルとディレクトリがインストールされています。)
apache2-mpm-worker を削除しています ...
[....] Stopping web server: apache2apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
[ ok waiting ..
以前に未選択のパッケージ apache2-mpm-prefork を選択しています。
(データベースを読み込んでいます ... 現在 79203 個のファイルとディレクトリがインストールされています。)
(.../apache2-mpm-prefork_2.2.22-13+deb7u6_armhf.deb から) apache2-mpm-prefork を展開してい ます...
apache2-mpm-prefork (2.2.22-13+deb7u6) を設定しています ...
[....] Starting web server: apache2apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
. ok
以前に未選択のパッケージ lsof を選択しています。
(データベースを読み込んでいます ... 現在 79208 個のファイルとディレクトリがインストールされています。)
(.../lsof_4.86+dfsg-1_armhf.deb から) lsof を展開しています...
以前に未選択のパッケージ php5-common を選択しています。
(.../php5-common_5.4.44-0+deb7u1_armhf.deb から) php5-common を展開しています...
以前に未選択のパッケージ libonig2 を選択しています。
(.../libonig2_5.9.1-1_armhf.deb から) libonig2 を展開しています...
以前に未選択のパッケージ libqdbm14 を選択しています。
(.../libqdbm14_1.8.78-2_armhf.deb から) libqdbm14 を展開しています...
以前に未選択のパッケージ libapache2-mod-php5 を選択しています。
(.../libapache2-mod-php5_5.4.44-0+deb7u1_armhf.deb から) libapache2-mod-php5 を展開しています...
以前に未選択のパッケージ php5 を選択しています。
(.../php5_5.4.44-0+deb7u1_all.deb から) php5 を展開しています...
以前に未選択のパッケージ php5-cli を選択しています。
(.../php5-cli_5.4.44-0+deb7u1_armhf.deb から) php5-cli を展開しています...
man-db のトリガを処理しています ...
lsof (4.86+dfsg-1) を設定しています ...
php5-common (5.4.44-0+deb7u1) を設定しています ...

Creating config file /etc/php5/mods-available/pdo.ini with new version
libonig2 (5.9.1-1) を設定しています ...
libqdbm14 (1.8.78-2) を設定しています ...
libapache2-mod-php5 (5.4.44-0+deb7u1) を設定しています ...

Creating config file /etc/php5/apache2/php.ini with new version
[....] Restarting web server: apache2apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
 ... waiting apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
. ok
php5 (5.4.44-0+deb7u1) を設定しています ...
php5-cli (5.4.44-0+deb7u1) を設定しています ...

Creating config file /etc/php5/cli/php.ini with new version
update-alternatives: /usr/bin/php (php) を提供するために 自動モード で /usr/bin/php5 を使います
root@satoraspi:~#

……と、いうわけで、サクッと入る。

PHPの作動を確かめる

 それでは早速……。

root@satoraspi:/var/www# ログアウト
toshio@satoraspi:~$ cd /var/www
toshio@satoraspi:/var/www$ vi infotest.php

 で、中身はこじんまりとこう書いて……

<html>
<head></head>
<body>
<?phpinfo();?>
</body>
</html>

 早速ブラウザで見ると……

raspi-phpinfo

うん。動いちょる動いちょる。

さっそくPHPでLチカ

 さて、次に、phpからGPIOだな。マンネリだけどやっぱり「Lチカ」か。

「web2LED.php」

<html>
 <head>
  <meta name="Editor" content="vim">
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
  <link rel="icon" href="favicon.ico" type="image/x-icon" />
  <link rel="Shortcut Icon" type="image/x-icon" href="favicon.ico" />
  <title>PHPでLチカ</title>
  <meta http-equiv="Keyword" content="佐藤俊夫, 佐藤, 俊夫, SATOTOSHIO, SatoToshio, sato, toshio, Raspberry Pi, Raspberry Pi 2 Model B">
 </head>
 <body bgcolor="#888888">
<body>
  <center>
  <h1>PHPでLチカ</h1>
  <hr>
  <form method="POST">
  <input type="submit" name="on"  value="LED on"><br>
  <input type="submit" name="off" value="LED off">
  </form>
  </center>
<?
ini_set( 'display_errors', 1 );
file_put_contents('/sys/class/gpio/export', 17);
file_put_contents('/sys/class/gpio/gpio17/direction', 'out');
if(isset($_POST['on'])){
  file_put_contents('/sys/class/gpio/gpio17/value', 1);
  print("LED ON.");
}elseif(isset($_POST['off'])){
  file_put_contents('/sys/class/gpio/gpio17/value', 0);
  print("LED OFF.");
}
file_put_contents('/sys/class/gpio/unexport', 17);
?>
</body>
</html>

 ブレッドボードにLEDと330Ωの抵抗を直列につけて、17番ピンとアースにつなぐ。

IMG_3313

 で、こういうフォームになるのだが……

web2LED_permission_deny

 いや、そりゃまあ、動くわけないわな、GPIOはrootでなきゃ読み書きできんのだから。

GPIOのパーミションの調整

 えーっと、どうやったらいいかな、ということで、

  • 「sudoする」
  • 「GPIOのアクセス権をヌルくする」
  • 「PHPの実行ユーザを強くする」
  • 「何かをSUID」

……などと、いろいろあるが、どうも、どれもいまいち、ピンと来ないな……。

 まあ、GPIOのアクセスをヌルくする、これかなあ……。

toshio@satoraspi:~$ cd /sys/class
toshio@satoraspi:/sys/class$ su
パスワード:
root@satoraspi:/sys/class# chmod -R 777 gpio
root@satoraspi:/sys/class# ls -Flad gpio
drwxrwxrwx 2 root gpio 0  8月 30 13:20 gpio/
root@satoraspi:/sys/class#

 なんっか、もう、力いっぱい777丸出しですけどね(笑)。多分、700とか760でも大丈夫じゃないかなあ。試してないけど。

 で、まあ、これで、フォームをクリックするとLEDが点いたり消えたりする。

Raspberry Pi + Apache + PHP + SSRでAC100Vの家電製品を制御

 これをそのまま、いつぞやArduinoでやったSSR(ソリッド・ステート・リレー)につなぐと、家電製品のオン・オフなどができるわけだ。

SSRモジュール
IMG_3047

 では、やってみよう。

Raspberry Pi 2で扇風機のオン・オフ

 真ん中の黒い箱がSSRだ。Arduinoは5V、Raspberry Pi 2は3.3Vで電圧が違うが、このSSRは3Vから8Vまでの入力を受け付けるので、大丈夫なのである。

空の写真リベンジ

投稿日:

 先週試したAdafruit製の「小型TTLシリアルjpegカメラ」での間欠撮影先週はどうしたわけか同じ画像ばかり撮れてしまい、失敗である。

 (チナミに、このカメラのメーカーの「Adafruit」という会社、有名なマッシモ・バンジのTEDの中で紹介されていたことに気付いた。)

https://youtube.com/watch?v=UoBUXOOdLXY%3Ft%3D5m50s

 気を取り直して、スケッチを直す。撮影時のカメラのステータスを確認し、撮れていなければ何回でも撮り続ける。

「while(撮れてない)撮る;」

……というわけだ。まあ、万が一ハードウェアエラーなどがあるとループが回り続けるので良くないが、ループが回り続けようが結局のところはモノとしては電源を入れ直す他にどうしようもないので、こんなものだろう。

 それと、撮影が終わったらカメラをそのつどリセットすることにした。また、既に存在するファイル名は避けるようにした。こういう時、Arduinoには書式文字列付きの「sprintf」がないので、少し不便だなと思う。

 夜明けから日没までの一日の空の雲を撮りたいので、天気予報を見て雨が降らぬ確信を持ってから、昨夜寝る前にベランダにカメラをセットしておいた。朝早く起きるより楽だからだ。夜のうちに1000枚くらい写真が撮れてしまうが、SDカードには余裕があるので大丈夫である。

 昼間は用事があるのでカメラの面倒は見れないが、放置しておけば淡々と写真は撮れていく。

IMG_3143

 で、撮れた写真をWindows Movie Makerに流し込むと、微速撮影動画の一丁上がりだ。

 スケッチは次のとおりである。

//
//  camera2Web.ino
//    27.07.20(月) 0850~
//    佐藤俊夫
//    Adafruit製小型TTLシリアルJPEGカメラ+ETHERNET SHIELD 2で
//    間欠撮影をし、Webでダウンロードできるようにする。
//
#include <Adafruit_VC0706.h>
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <Ethernet2.h>

#define CHIPSELECT 4

SoftwareSerial CAMCONNECTION(2, 3);
Adafruit_VC0706 CAM = Adafruit_VC0706(&CAMCONNECTION);
const unsigned long int INTERVAL = 30L * 1000L;
byte MAC[] = {  0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74 };
IPAddress IP(192, 168, 1, 129);
EthernetServer SERVER(80);
EthernetClient CLIENT;

void setup() {
  pinMode(10, OUTPUT);
  if(!SD.begin(CHIPSELECT)) return;
  if(!CAM.begin()) return;
  CAM.setImageSize(VC0706_320x240);
  Ethernet.begin(MAC, IP);
  SERVER.begin();
  delay(1000);
}

void loop() {
  static unsigned long int prevtime = 0;
  char c;
  String rstr = "";
  //  INTERVALおきに写真を撮る
  if(millis() >= prevtime + INTERVAL){
    prevtime = millis();
    takePicture();
  }
  //  Webサーバ
  CLIENT = SERVER.available();
  if(CLIENT) {
    while(CLIENT.connected()) {
      if(CLIENT.available()) {
        c = CLIENT.read();
        rstr += c;
        if(rstr.endsWith("\r\n")){
          break;
        }
      }
    }
    if(rstr.indexOf("IMG") >= 0){
      String filename = "DCIM/";
      char cfilename[17];
      filename.concat(rstr.substring(rstr.indexOf("IMG"), rstr.indexOf("JPG") + 3));
      filename.toCharArray(cfilename, 17);
      CLIENT.println("HTTP/1.1 200 OK");
      CLIENT.println("Content-Type: image/jpg");
      CLIENT.println("Connection: close");
      CLIENT.println();
      File img = SD.open(cfilename);
      while(img.available()){
        CLIENT.write(img.read());
      }
      img.close();
    }else{
      sendform();
    }
    rstr = "";
    delay(1);
    // close the connection:
    CLIENT.stop();
  }
  delay(20);
}

void sendform(){
  //  フォームを送る。
  CLIENT.println("HTTP/1.1 200 OK");
  CLIENT.println("Content-Type: text/html");
  CLIENT.println("Connection: close");
  CLIENT.println();
  CLIENT.println("<!DOCTYPE HTML>");
  CLIENT.println("<html><head></head><body><center>");
  File dcim = SD.open("/DCIM");
  while(true) {
    File imgfile =  dcim.openNextFile();
    if(!imgfile){
      dcim.rewindDirectory();
      break;
    }
    CLIENT.write("<a href=\"");
    CLIENT.write(imgfile.name());
    CLIENT.write("\">");    
    CLIENT.write(imgfile.name());
    CLIENT.println("</a><br>");
    imgfile.close();    
  }
  dcim.close();
  CLIENT.println("</center></body></html>");
}

void takePicture(){
  static unsigned int pnum = 0;
  char filename[] = "DCIM/img0000.jpg";
  while(!CAM.takePicture());
  do{
    filename[8]  = '0' + pnum / 1000;
    filename[9]  = '0' + (pnum / 100) % 10;
    filename[10] = '0' + (pnum /  10) % 10;
    filename[11] = '0' + pnum % 10;
    pnum ++;
  }while(SD.exists(filename));
  if(pnum > 9999) pnum = 0;
  File imgFile = SD.open(filename, FILE_WRITE);
  uint16_t jpglen = CAM.frameLength();
  pinMode(8, OUTPUT);
  while (jpglen > 0) {
    uint8_t *buffer;
    uint8_t bytesToRead = min(32, jpglen);
    buffer = CAM.readPicture(bytesToRead);
    imgFile.write(buffer, bytesToRead);
    jpglen -= bytesToRead;
  }
  while(!CAM.reset());
  imgFile.close();
}




Webでサービスできるカメラ

投稿日:

 一昨日遊んだカメラ。今日はこれにETHERNET SHIELD 2を取り付けて遊んでみる。

  •  間欠的に写真を撮り続ける。
  •  SDに保存する。
  •  ウェブアクセスがあると、一覧でサービスする。

 まあ、これくらいで。サムネイル画像などハデに出したい気もするが、Arduinoはメモリも小さく、そんなに気の利いたウェブサービスはできない。

 プロトタイピングシールドのブレッドボードに組み付ける。

IMG_3136

 まず、スケッチはこんなところだろう。

//
//  camera2Web.ino
//    27.07.20(月) 0850~
//    佐藤俊夫
//    Adafruit製小型TTLシリアルJPEGカメラ+ETHERNET SHIELD 2で
//    間欠撮影をし、Webでダウンロードできるようにする。
//
#include <Adafruit_VC0706.h>
#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <Ethernet2.h>

#define CHIPSELECT 4

SoftwareSerial CAMCONNECTION(2, 3);
Adafruit_VC0706 CAM = Adafruit_VC0706(&CAMCONNECTION);
const unsigned long int INTERVAL = 30L * 1000L;
byte MAC[] = {  0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74 };
IPAddress IP(192, 168, 1, 129);
EthernetServer SERVER(80);
EthernetClient CLIENT;

void setup() {
  pinMode(10, OUTPUT);
  if(!SD.begin(CHIPSELECT)) return;
  if(!CAM.begin()) return;
  CAM.setImageSize(VC0706_320x240);
  Ethernet.begin(MAC, IP);
  SERVER.begin();
  delay(1000);
}

void loop() {
  static unsigned long int prevtime = 0;
  char c;
  String rstr = "";
  //  INTERVALおきに写真を撮る
  if(millis() >= prevtime + INTERVAL){
    prevtime = millis();
    takePicture();
  }
  //  Webサーバ
  CLIENT = SERVER.available();
  if(CLIENT) {
    while(CLIENT.connected()) {
      if(CLIENT.available()) {
        c = CLIENT.read();
        rstr += c;
        if(rstr.endsWith("\r\n")){
          break;
        }
      }
    }
    if(rstr.indexOf("IMG") >= 0){
      String filename = "DCIM/";
      char cfilename[17];
      filename.concat(rstr.substring(rstr.indexOf("IMG"), rstr.indexOf("JPG") + 3));
      filename.toCharArray(cfilename, 17);
      CLIENT.println("HTTP/1.1 200 OK");
      CLIENT.println("Content-Type: image/jpg");
      CLIENT.println("Connection: close");
      CLIENT.println();
      File img = SD.open(cfilename);
      while(img.available()){
        CLIENT.write(img.read());
      }
      img.close();
    }else{
      sendform();
    }
    rstr = "";
    delay(1);
    // close the connection:
    CLIENT.stop();
  }
  delay(20);
}

void sendform(){
  //  フォームを送る。
  CLIENT.println("HTTP/1.1 200 OK");
  CLIENT.println("Content-Type: text/html");
  CLIENT.println("Connection: close");
  CLIENT.println();
  CLIENT.println("<!DOCTYPE HTML>");
  CLIENT.println("<html><head></head><body><center>");
  File dcim = SD.open("/DCIM");
  while(true) {
    File imgfile =  dcim.openNextFile();
    if(!imgfile){
      dcim.rewindDirectory();
      break;
    }
    CLIENT.write("<a href=\"");
    CLIENT.write(imgfile.name());
    CLIENT.write("\">");    
    CLIENT.write(imgfile.name());
    CLIENT.println("</a><br>");
    imgfile.close();    
  }
  dcim.close();
  CLIENT.println("</center></body></html>");
}

void takePicture(){
  static unsigned int pnum = 0;
  char filename[] = "DCIM/img0000.jpg";
  CAM.takePicture();
  filename[8]  = '0' + pnum / 1000;
  filename[9]  = '0' + (pnum / 100) % 10;
  filename[10] = '0' + (pnum /  10) % 10;
  filename[11] = '0' + pnum % 10;
  pnum ++;
  if(pnum > 9999) pnum = 0;
  if(SD.exists(filename)) return;
  File imgFile = SD.open(filename, FILE_WRITE);
  uint16_t jpglen = CAM.frameLength();
  pinMode(8, OUTPUT);
  while (jpglen > 0) {
    uint8_t *buffer;
    uint8_t bytesToRead = min(32, jpglen);
    buffer = CAM.readPicture(bytesToRead);
    imgFile.write(buffer, bytesToRead);
    jpglen -= bytesToRead;
  }
  imgFile.close();
}

  で、電源をつないで放置しておくと、写真が撮れるわけだ。既存のファイル名を避けるような芸コマなことはしてないけど、これはこれでけっこう面白い。

 いつもの100円ショップのアクリル枠にねじ止めする。このカメラは上下が逆に映るので、こうすると丁度カメラが逆さまになって具合が良い。

IMG_3138

 それで、以前にWIZnetで紹介されて愉快だったアレのリベンジをやってみよう。携帯用のカメラホルダーに取り付け、ベランダに出して放置。

IMG_3139

いよいよ多機能リモコン

投稿日:

 LEDを強力に光らせることが出来たので、いよいよWebサーバつき多機能リモコンを作成する。卓上などに置いておき、ネットワークにつないで、スマホなどから複数の電化製品を操作できるというものだ。

 ここでは、いくつかのテクニックを使った。

 一つは、フォームが大きくなってしまい、ハードコーディングするとメモリが足りなくなる。そこで、SDカード内にHTMLを置き、これを読み出すようにした。

 同様に、リモコンから読み取った数値データが大きくなって、普通にハードコーディングしたのではメモリが不足する。そこで、「PROGMEM」というキーワードを使って、フラッシュメモリ内にデータを置き、これを読み出すようにした。

IMG_3134 ETHERNET SHIELD 2を遺憾なく使う。SDカードを取り付けられるから、そこにHTMLを書き込んでおけばよい。FETをつけたブレッドボードと一緒に、買っておいたSparkfunの基盤に固定する。

 SDカード内には、次のようなHTMLを置き、ファイル名を「irform.htm」とする。

<html>
 <head>
  <meta name="Editor" content="Notepad.exe">
  <meta http-equiv="Content-Type" content="text/html;charset=Shift_JIS">
  <title>Webリモコン</title>
  <basefont size=4>
 </head>

 <body bgcolor="#ddffdd">
  <center>
   <h1><b>Webリモコン</b></h1>
     <table>
      <tr><td> 作成者   </td>
       <td align="right">佐藤俊夫</td></tr>
      <tr><td> 作成日時 </td>
       <td align="right">27.07.19 (日) 1835</td></tr>
     </table>
  </center>
  <hr>
  <center>
    <form method="get" name="irremote">
    <table border=1>
      <tr><th>機器</th><th>ボタン</th></tr>
      <tr>
        <td rowspan=4>扇風機</td>
        <td><input submit type="submit" value="入/風量" name="fan_on"></td>
      </tr>
        <tr><td><input submit type="submit" value="タイマー" name="fan_timer"></td></tr>
        <tr><td><input submit type="submit" value="首振" name="fan_swing"></td></tr>
        <tr><td><input submit type="submit" value="切" name="fan_off"></td></tr>
      </tr>
      <tr>
        <td rowspan=5>テレビ</td>
        <td><input submit type="submit" value="入/切" name="tv_on_off"></td>
      </tr>
        <tr><td><input submit type="submit" value="音量大" name="tv_volup"></td></tr>
        <tr><td><input submit type="submit" value="音量小" name="tv_voldown"></td></tr>
        <tr><td><input submit type="submit" value="チャンネル>" name="tv_chup"></td></tr>
        <tr><td><input submit type="submit" value="チャンネル<" name="tv_chdown"></td></tr>
    </table>
    </form>
  </center>
 </body>
</html>

irform 上のHTMLの見た目はこんな感じだ。

 スケッチは次のようになる。

//
//  Web2IRremote.ino
//    リモコンをウェブで操作する。
//    27.07.25(日) 1930
//    佐藤俊夫
//
#include <SPI.h>
#include <Ethernet2.h>
#include <SD.h>
#include <IRremote.h>
#include <avr/pgmspace.h>
//
byte mac[] = {  0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74 };
IPAddress ip(192, 168, 1, 129);
EthernetServer SERVER(80);
EthernetClient CLIENT;
IRsend irsend;
PROGMEM
  const unsigned int
    fan_on[]     = {4500,2150, 600,500, 650,500, 600,500, 600,500, 600,1650, 600,1600, 650,1550, 650,500, 600,1600, 650,1600, 600,1600, 650,450, 600,1600, 650,500, 600,500, 650,500, 600,1600, 600,500, 650,500, 600,500, 600,500, 600,500, 600,1650, 600,500, 600,500, 600,500, 650,1600, 600,1600, 600,1650, 600,1600, 600,500, 650,500, 600,0},
    fan_timer[]  = {4500,2150, 550,550, 550,600, 550,550, 600,500, 550,1700, 500,1700, 550,1650, 550,600, 550,1650, 550,1700, 500,1700, 550,600, 500,1700, 550,550, 550,550, 550,600, 500,1700, 550,600, 500,600, 500,600, 500,600, 550,550, 550,1700, 550,600, 450,600, 550,550, 550,600, 500,1700, 550,1650, 550,1700, 550,1650, 550,600, 500,0},
    fan_swing[]  = {4450,2200, 600,550, 550,500, 600,550, 550,550, 550,1700, 550,1650, 550,1700, 550,550, 550,1650, 550,1700, 550,1650, 550,550, 600,1650, 550,550, 550,550, 550,550, 600,1650, 550,550, 550,550, 600,550, 550,550, 550,550, 600,1600, 600,550, 550,550, 550,1650, 600,1550, 650,1700, 550,1650, 550,550, 550,550, 600,550, 550,0},
    fan_off[]    = {4450,2250, 550,550, 600,550, 550,500, 600,550, 550,1650, 600,1650, 550,1650, 600,550, 550,1650, 550,1650, 600,1650, 550,550, 550,1700, 550,550, 550,550, 550,550, 550,1700, 550,550, 550,550, 550,550, 600,550, 550,550, 550,1650, 550,550, 600,550, 550,1650, 600,1650, 550,550, 550,1700, 550,500, 600,550, 550,1650, 600,0},
    tv_on_off[]  = {3400,1750, 400,500, 350,1350, 400,500, 350,500, 400,500, 350,500, 400,500, 350,450, 400,500, 400,500, 350,500, 400,500, 350,500, 350,1350, 400,500, 400,500, 350,450, 400,500, 400,500, 350,450, 400,500, 400,500, 350,500, 400,1300, 400,500, 400,450, 400,500, 400,500, 350,500, 350,500, 400,450, 400,450, 400,1350, 400,500, 400,1300, 400,1350, 400,1350, 400,1350, 400,450, 400,500, 400,1300, 400,500, 400,1300, 400,1350, 400,1350, 400,1350, 400,500, 350,1350, 400,0},
    tv_volup[]   = {3400,1750, 400,500, 400,1300, 400,500, 400,500, 350,500, 450,400, 400,500, 350,500, 400,500, 350,500, 350,500, 400,500, 350,500, 400,1300, 400,500, 400,450, 400,500, 350,500, 400,500, 350,500, 400,500, 350,500, 350,500, 400,1300, 450,450, 400,500, 350,500, 400,500, 350,500, 400,450, 400,500, 350,500, 400,500, 350,450, 400,500, 400,500, 350,500, 450,1250, 400,500, 400,500, 350,500, 400,450, 400,500, 350,500, 400,500, 350,1350, 400,450, 400,1350, 400,0},
    tv_voldown[] = {3400,1750, 400,500, 350,1350, 400,500, 400,450, 400,500, 350,500, 400,450, 400,500, 400,500, 350,500, 350,500, 400,500, 350,500, 350,1300, 450,500, 400,500, 350,450, 400,500, 450,450, 350,500, 400,450, 400,450, 400,500, 400,1300, 450,500, 350,500, 350,500, 400,500, 350,450, 400,500, 400,500, 350,500, 400,1300, 400,500, 400,450, 400,500, 400,500, 350,1350, 400,500, 350,500, 400,1300, 400,500, 400,500, 350,500, 350,500, 400,1300, 450,500, 350,1350, 400,0},
    tv_chup[]    = {3400,1750, 400,500, 400,1350, 450,400, 400,450, 400,500, 450,400, 400,450, 400,500, 450,450, 450,400, 450,450, 400,400, 400,500, 450,1250, 450,500, 350,450, 500,400, 450,400, 400,500, 350,500, 450,450, 350,500, 450,450, 450,1250, 400,500, 450,400, 400,500, 400,450, 450,400, 450,450, 350,500, 450,400, 450,450, 350,500, 450,1250, 400,500, 450,1250, 500,1250, 500,400, 450,450, 350,500, 450,450, 350,1350, 450,450, 400,1300, 450,1250, 500,450, 400,1250, 450,0},
    tv_chdown[]  = {3500,1650, 450,500, 400,1300, 400,500, 450,400, 350,500, 400,450, 500,400, 450,450, 350,450, 400,500, 400,500, 350,500, 400,450, 450,1300, 450,450, 350,450, 450,500, 350,500, 450,400, 450,400, 400,500, 350,500, 450,400, 400,1350, 450,400, 500,400, 450,450, 450,400, 400,500, 350,500, 350,500, 400,500, 350,1350, 450,450, 350,1350, 400,500, 350,1350, 500,1250, 450,450, 450,400, 450,1250, 500,400, 450,1300, 450,450, 400,1300, 450,1250, 450,500, 350,1350, 450,0};
////
void setup() 
{ 
  const int chipSelect = 4;
  Ethernet.begin(mac, ip);
  SERVER.begin();
  if (!SD.begin(chipSelect)) {
    return;
  }
} 
 
void loop() 
{ 
  //  Webサーバの動作
  char c;
  String rstr = "";
  CLIENT = SERVER.available();
  if (CLIENT) {
    while (CLIENT.connected()) {
      if (CLIENT.available()) {
        c = CLIENT.read();
        rstr += c;
        if(rstr.endsWith("\r\n")){
          break;
        }
      }
    }
    if(rstr.indexOf("fan_on=") >= 0){
      unsigned int buf[sizeof(fan_on) / sizeof(*fan_on)];
      for(int i = 0; i < sizeof(fan_on) / sizeof(*fan_on); i++){
        buf[i] = pgm_read_word(fan_on + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    else if(rstr.indexOf("fan_timer=") >= 0){
      unsigned int buf[sizeof(fan_timer) / sizeof(*fan_timer)];
      for(int i = 0; i < sizeof(fan_timer) / sizeof(*fan_timer); i++){
        buf[i] = pgm_read_word(fan_timer + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    else if(rstr.indexOf("fan_swing=") >= 0){
      unsigned int buf[sizeof(fan_swing) / sizeof(*fan_swing)];
      for(int i = 0; i < sizeof(fan_swing) / sizeof(*fan_swing); i++){
        buf[i] = pgm_read_word(fan_swing + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    else if(rstr.indexOf("fan_off=") >= 0){
     unsigned int buf[sizeof(fan_off) / sizeof(*fan_off)];
     for(int i = 0; i < sizeof(fan_off) / sizeof(*fan_off); i++){
        buf[i] = pgm_read_word(fan_off + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    else if(rstr.indexOf("tv_on_off=") >= 0){
     unsigned int buf[sizeof(tv_on_off) / sizeof(*tv_on_off)];
     for(int i = 0; i < sizeof(tv_on_off) / sizeof(*tv_on_off); i++){
        buf[i] = pgm_read_word(tv_on_off + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    else if(rstr.indexOf("tv_volup=") >= 0){
     unsigned int buf[sizeof(tv_volup) / sizeof(*tv_volup)];
     for(int i = 0; i < sizeof(tv_volup) / sizeof(*tv_volup); i++){
        buf[i] = pgm_read_word(tv_volup + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    else if(rstr.indexOf("tv_voldown=") >= 0){
     unsigned int buf[sizeof(tv_voldown) / sizeof(*tv_voldown)];
     for(int i = 0; i < sizeof(tv_voldown) / sizeof(*tv_voldown); i++){
        buf[i] = pgm_read_word(tv_voldown + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    else if(rstr.indexOf("tv_chup=") >= 0){
     unsigned int buf[sizeof(tv_chup) / sizeof(*tv_chup)];
     for(int i = 0; i < sizeof(tv_chup) / sizeof(*tv_chup); i++){
        buf[i] = pgm_read_word(tv_chup + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    else if(rstr.indexOf("tv_chdown=") >= 0){
     unsigned int buf[sizeof(tv_chdown) / sizeof(*tv_chdown)];
     for(int i = 0; i < sizeof(tv_chdown) / sizeof(*tv_chdown); i++){
        buf[i] = pgm_read_word(tv_chdown + i);
      }
      irsend.sendRaw(buf, sizeof(buf) / sizeof(buf[0]), 38);
    }
    rstr = "";
    sendform();
    delay(1);
    // close the connection:
    CLIENT.stop();
  }
  delay(20);
}
void sendform(){
  //  フォームを送る。
  CLIENT.println("HTTP/1.1 200 OK");
  CLIENT.println("Content-Type: text/html");
  CLIENT.println("Connection: close");
  CLIENT.println();
  CLIENT.println("<!DOCTYPE HTML>");
  File html = SD.open("irform.htm");
  if (html) {
    while (html.available()) {
      CLIENT.write(html.read());
    }
    html.close();
  } 
}

IMG_3135 勿論、ただのWebであるから、このようにスマホの他、タブレットなどからも操作可能である。また、ルータでポートフォワードすれば、外出先からの操作も可能である。

WIZnetでまた紹介され、嬉しい

投稿日:

 このところ凝っているArduinoでの遊び、そんなにお金もかからないし、何より楽しい。

 先日、私が作ったデジタルカメラのシャッターをネット経由で切る工夫が韓国「WIZnet」のサイトで紹介され、とても嬉しかった

 この「WIZnet」というところは私が買った「ETHERNET SHIELD 2」に搭載されているW5500というコントローラのメーカーなのだ。それで、私のブログにコメントをつけてくれ、サイトで紹介してくれたのであった。

 先日、安物の扇風機にWebインターフェイスを実装し、温度で制御する、という試みをやり、楽しかったので、「こんどはこんなのが出来ました~」とWIZnetのサイトに報告したら、それも紹介してあげましょう、と返事があって、このとおり紹介された。

 私の元の記事では「ウェブ扇風機」というダサい名前だったが、こういうふうに「Web controller for smart Fan」と書いてもらうと、なんだかカッコイイじゃないの(笑)。

 いやあ、Arduinoって、楽しいなあw。

ウェブ扇風機

投稿日:

 昨日試した扇風機遊びを少し進め、温度制御を付けてみたい。

 おあつらえ向きに、最初に買った「Seeedstudio SIDEKICK BASIC KIT」には、サーミスタが入っている。これで温度を検知して、温度ごとに扇風機の回転を制御するわけだ。値の変更などはETHERNET SHIELD 2をつなぎ、ウェブインターフェイスで行うと面白いだろう。

 以前にも試したが、しかし、このキット付属のサーミスタは情報が少なくて困る。そこで、ちゃんと計算してそれなりの温度測定をしてみたい。以前は測りたい温度近傍の特性値をテーブルから拾って2次式で近似しただけであった。

 スペックシートによれば、-55℃で10583.3Ω、+125℃で1.277Ωになる、とある。常温付近では0℃で190.07Ω、40℃で24.87Ωだ。もしサーミスタ直付けでArduinoから5V給電すれば、-55℃のときは0.47mAだが、0℃で26.3mA、40℃で201mAと、Arduinoに流せる電流の20mAを大きく逸脱してしまう。

 40度付近でも大丈夫なように、抵抗を付加しなければならない。40℃の時に流したい電流を5mAと仮定すれば、

IMG_3075

……というような計算で975Ωくらいつなげておけばよいということになる。

 しかし、手持ちの抵抗は、キットに入っていた330Ω・1kΩ・10kΩの3種類しかないから、これで賄うしかない。

 一番大きい抵抗は10kΩだから、これで計算しなおすと、40℃の時で

5V / (24.87Ω + 10kΩ) = 0.5mA

2番目は1kΩ、同じく40℃の時で

5V / (24.87Ω + 1kΩ) = 4.88mA

同様に3番目の330Ωだと

5V / (24.87Ω + 330Ω) = 14mA

…ということになる。間をとって、1kΩで回路を作ってみよう。

 次に、サーミスタは抵抗から温度を知る。一方、Arduinoは電圧からデジタル値を知る。したがって、電圧からまず抵抗値を知らなければその先の温度測定に進めない。

 先の電流調整用の1kΩ抵抗をR0として含め、現在のサーミスタの抵抗値を知るには、一般に式は次のようになろう。

IMG_3079

 これをソースコードに表せば、次のようになる。

  const float v0 = 5.0, r0 = 1000.0;  //  Arduino +5Vと電流調整抵抗1kΩ
  const int resolution = 1024;  //  アナログ入力の分解能
  int srcVal = 0;
  float vt = 0.0, rt = 0.0;
  
  srcVal = analogRead(THERMISTOR);
  vt = srcVal * (v0 / (resolution - 1));
  rt = (v0 * r0 - vt * r0) / vt;

 次に、知った抵抗値から温度を知る計算である。

 サーミスタの抵抗は対数特性を持っているので、関数は対数モデルになる。また、サーミスタの特性を表す重要な値は「B値」と呼ばれるものと、Ta(温度)、R0(抵抗)の3つで、それらはスペックシートに書いてある。

 TaとR0については、「温度がTaのとき、抵抗はR0になる」というものだ。私の手元のサーミスタは、スペックシートによると、

Ta = 25℃
R0 = 50kΩ

……とある。

 B値は「抵抗の対数と、温度の比」である。これもスペックシートに関係式が書いてある。

 これらのスペックシートの値と、知った抵抗値から温度を求める式は、次のようになる。

IMG_3080

 これを、先の抵抗値を知る部分と併せて、Arduinoで使える関数にすれば、このようになろうか。

float tempMesure(){
  const float B = 4350.0, Ta = 25.0, Rt0 = 50000.0;  //  MF11-503Kスペックシート記載
  const float K = 273.15;  //  熱力学温度の定数
  const float v0 = 5.0, r0 = 1000.0;  //  Arduino +5Vと電流調整抵抗1kΩ
  const int resolution = 1024;  //  アナログ入力の分解能
  int srcVal = 0;
  float vt = 0.0, rt = 0.0;
  
  srcVal = analogRead(THERMISTOR);
  vt = srcVal * (v0 / (resolution - 1));
  rt = (v0 * r0 - vt * r0) / vt;
  return(1.0 / (log(rt / Rt0) / B + 1.0 / (Ta + K)) - K);
}

 これを用いて、少し真面目っぽい温度測定スケッチを書けば、次のようになる。

//
//  thermistor2temp.ino
//    サーミスタでわりと真面目に温度を測る。
//    27.7.5(日)
//    佐藤俊夫
//
const int THERMISTOR = 1;

void setup() 
{ 
  Serial.begin(9600);
} 
 
void loop() 
{ 
  float t = 0.0;
  
  t = tempMesure();
  Serial.print("Temp = ");
  Serial.print(t);
  Serial.println("C");
  delay(500);
}

float tempMesure(){
  const float B = 4350.0, Ta = 25.0, Rt0 = 50000.0;  //  MF11-503Kスペックシート記載
  const float K = 273.15;  //  熱力学温度の定数
  const float v0 = 5.0, r0 = 1000.0;  //  Arduino +5Vと電流調整抵抗1kΩ
  const int resolution = 1024;  //  アナログ入力の分解能
  int srcVal = 0;
  float vt = 0.0, rt = 0.0;
  
  srcVal = analogRead(THERMISTOR);
  vt = srcVal * (v0 / (resolution - 1));
  rt = (v0 * r0 - vt * r0) / vt;
  return(1.0 / (log(rt / Rt0) / B + 1.0 / (Ta + K)) - K);
}

 次に、温度に応じて扇風機の回転数が変わるようにしよう。先日作った「ソリッドステート・リレーモジュール」を遺憾なく使用する。

ソリッドステート・リレーモジュール
IMG_3081

 このモジュールの内部には、秋月電子の「ソリッド・ステート・リレー(SSR)キット 25A(20A)タイプ」が組み付けてある。

 27℃で1/fゆらぎエフェクト、28℃で弱風、29℃で強風、とでもしてみようか。1/fゆらぎエフェクトには、先週書いた関数をそのままコピペする。

IMG_3083

//
//  thermistor2windFan.ino
//    サーミスタで温度を測り、扇風機を制御する。
//    27.7.5(日)
//    佐藤俊夫
//
const int THERMISTOR = 1, WINDFAN = 9;
void setup() 
{ 
  Serial.begin(9600);
  pinMode(WINDFAN, OUTPUT);
} 
 
void loop() 
{ 
  const int half = 128, full = 255;
  const float lowTemp = 27.0, midTemp = 28.0, highTemp = 29.0; 
  float t = 0.0, f = 0.0;
  
  t = tempMesure();
  Serial.print("temp=");
  Serial.println(t);
  if(t > highTemp){
    analogWrite(WINDFAN, full);
  }else
  if(t > midTemp){
    analogWrite(WINDFAN, half);
  }else
  if(t > lowTemp){
    f = f1Fluctuation();
    analogWrite(WINDFAN, f);
  }else{
    analogWrite(WINDFAN, 0);
  }
  delay(20);
}

float tempMesure(){
  const float B = 4350.0, Ta = 25.0, Rt0 = 50000.0;  //  MF11-503Kスペックシート記載
  const float K = 273.15;  //  熱力学温度の定数
  const float v0 = 5.0, r0 = 1000.0;  //  Arduino +5Vと電流調整抵抗1kΩ
  const int resolution = 1024;  //  アナログ入力の分解能
  int srcVal = 0;
  float vt = 0.0, rt = 0.0;
  
  srcVal = analogRead(THERMISTOR);
  vt = srcVal * (v0 / (resolution - 1));
  rt = (v0 * r0 - vt * r0) / vt;
  return(1.0 / (log(rt / Rt0) / B + 1.0 / (Ta + K)) - K);
}

int f1Fluctuation(){
  static float x = 0.1;
  if(x < 0.5){
    x = x + 2 * x * x;
  } 
  else {
    x = x - 2 * (1.0 - x) * (1.0 - x);
  }
  if(x < 0.05 || x > 0.995){
    x = random(10, 90) / 100.0;
  }
  return((int)(x * 255));
}

 回路図など、描くも愚かというか、こんな簡単なものである。

IMG_3084

 さて次に、ETHERNET SHIELD 2をつなぎ、この扇風機をWeb化する。昨日買っておいた「クリアランス確保用ピンソケット」が役に立つ。

IMG_3067

 組み付けるとこんな感じである。回路はネットにつながない場合と同じでよい。

IMG_3087

 こんなインターフェイスで動かす。

ネット扇風機インターフェイス

 設定した温度になると扇風機が回る。

IMG_3088

 スケッチはこのようになる。

//
//  web2thermistor_windFan.ino
//    サーミスタで温度を測り、扇風機を制御する。
//    27.7.5(日)
//    佐藤俊夫
//
#include <SPI.h>
#include <Ethernet2.h>
//
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0F, 0xF6, 0x74
};
IPAddress ip(192, 168, 1, 129);
EthernetServer SERVER(80);
EthernetClient CLIENT;
const int THERMISTOR = 1, WINDFAN = 9;
//
void setup() 
{ 
  Ethernet.begin(mac, ip);
  SERVER.begin();
  Serial.begin(9600);
  pinMode(WINDFAN, OUTPUT);
} 
 
void loop() 
{ 
  const int half = 128, full = 255;
  static float lowTemp = 27.0, midTemp = 28.0, highTemp = 29.0; 
  float t = 0.0, f = 0.0;
  //  Webサーバの動作
  char c;
  String rstr = "";
  CLIENT = SERVER.available();
  if (CLIENT) {
    while (CLIENT.connected()) {
      if (CLIENT.available()) {
        c = CLIENT.read();
        rstr += c;
        if(rstr.endsWith("\r\n")){
          break;
        }
      }
    }
    if(rstr.indexOf("low=") >= 0){
      lowTemp = rstr.substring(rstr.indexOf("low=") + 4, rstr.indexOf("&green=")).toInt();
      midTemp = rstr.substring(rstr.indexOf("mid=") + 4, rstr.indexOf("&blue=")).toInt();
      highTemp = rstr.substring(rstr.indexOf("high=") + 5, rstr.indexOf("&end")).toInt();
    }
    rstr = "";
    sendform(lowTemp, midTemp, highTemp);
    delay(1);
    // close the connection:
    CLIENT.stop();
  }
  // 温度測定
  t = tempMesure();
  Serial.print("temp=");
  Serial.println(t);
  if(t > highTemp){
    analogWrite(WINDFAN, full);
    Serial.println("high");
  }else
  if(t > midTemp){
    analogWrite(WINDFAN, half);
  }else
  if(t > lowTemp){
    f = f1Fluctuation();
    analogWrite(WINDFAN, f);
  }else{
    analogWrite(WINDFAN, 0);
  }
  delay(20);
}

float tempMesure(){
  //  Seeedstudio SIDEKICK BASIC KIT付属のサーミスタ「MF11-503K」で
  //  温度を測る。
  const float B = 4350.0, Ta = 25.0, Rt0 = 50000.0;  //  MF11-503Kスペックシート記載
  const float K = 273.15;  //  熱力学温度の定数
  const float v0 = 5.0, r0 = 1000.0;  //  Arduino +5Vと電流調整抵抗1kΩ
  const int resolution = 1024;  //  アナログ入力の分解能
  int srcVal = 0;
  float vt = 0.0, rt = 0.0;
  
  srcVal = analogRead(THERMISTOR);
  vt = srcVal * (v0 / (resolution - 1));
  rt = (v0 * r0 - vt * r0) / vt;
  return(1.0 / (log(rt / Rt0) / B + 1.0 / (Ta + K)) - K);
}

int f1Fluctuation(){
  //  間欠カオス法により0~255の間で1/fゆらぎを生成して返す。
  static float x = 0.1;
  if(x < 0.5){
    x = x + 2 * x * x;
  } 
  else {
    x = x - 2 * (1.0 - x) * (1.0 - x);
  }
  if(x < 0.05 || x > 0.995){
    x = random(10, 90) / 100.0;
  }
  return((int)(x * 255));
}

void sendform(float lowTemp, float midTemp, float highTemp){
  //  フォームを送る。
  char* formFirstHalf[] = {
    "<html>",
    "  <head>",
    "    <meta charset=\"utf-8\">",
    "  </head>",
    "  <body bgcolor='#ddddff'>",
    "    <center>",
    "      <h1>Arduino ネット扇風機</h1>",
    "      <form method='GET'>",
    "        <table>",
    "          <tr>",
    "  	    <th>ゆらぎ送風温度</th>",
    "  	    <th>弱風温度</th>",
    "  	    <th>強風温度</th>",
    "	  </tr>"
  };  //  14 num.
  char* formSecondHalf[] = {
    "        </table>",
    "        <input type='hidden' name='end'>",
    "        <input type='submit' value='セット'>",
    "      </form>",
    "    </center>",
    "  </body>",
    "</html>"
  };  // 7 num.
  int i = 0;

  CLIENT.println("HTTP/1.1 200 OK");
  CLIENT.println("Content-Type: text/html");
  CLIENT.println("Connection: close");
  CLIENT.println();
  CLIENT.println("<!DOCTYPE HTML>");
  for(i = 0; i < 14; i++){
    CLIENT.println(formFirstHalf[i]);
  }
  CLIENT.println("          <tr>");
  CLIENT.println("            <td>");
  CLIENT.println("           <input type='text' name='low' size='6em' value =");
  CLIENT.print(lowTemp);
  CLIENT.println(">");
  CLIENT.println("            </td>");
  CLIENT.println("            <td>");
  CLIENT.println("           <input type='text' name='mid' size='6em' value =");
  CLIENT.print(midTemp);
  CLIENT.println(">");
  CLIENT.println("            </td>");
  CLIENT.println("            <td>");
  CLIENT.println("           <input type='text' name='high' size='6em' value =");
  CLIENT.print(highTemp);
  CLIENT.println(">");
  CLIENT.println("            </td>");
  CLIENT.println("          </tr>");
  for(i = 0; i < 7; i++){
    CLIENT.println(formSecondHalf[i]);
  }

}






Perlとかphpなどの

投稿日:

 PerlとかPHPなどの、ダラダラと随筆風にプログラミングできるWeb向き言語に慣れると、ArduinoにETHERNET SHIELD 2を取り付けた時のCGI引数の処理にしんどさを覚えるのは確かだ。特に正規表現でいろいろやりたい、という場合が苦しい。

サーボコントロールのWeb汎用化

投稿日:

 今日、Arduino + ETHERNET SHIELD 2 で遊んでいて思ったのだが、同じGETの処理をするなら、

http://hogehoge.hoge/?start=10&hold=5000&release=50

……というような、汎用化したGET引数にすれば面白いかも、と思った。まあ、セキュリティ上よろしくないが。